otsu自适应阈值分割的算法描述和opencv实现,及其在肤色检测中的应用

 otsu算法选择使类间方差最大的灰度值为阈值,具有很好的效果
算法具体描述见otsu论文,或冈萨雷斯著名的数字图像处理那本书
这里给出程序流程:
1、计算直方图并归一化histogram
2、计算图像灰度均值avgValue.
3、计算直方图的零阶w[i]和一级矩u[i]
4、计算并找到最大的类间方差(between-class variance)
variance[i]=(avgValue*w[i]-u[i])*(avgValue*w[i]-u[i])/(w[i]*(1-w[i]))
对应此最大方差的灰度值即为要找的阈值
5、用找到的阈值二值化图像

我在代码中做了一些优化,所以算法描述的某些地方跟程序并不一致

 

otsu代码,先找阈值,继而二值化

 

更多情况下我们并不需要对每一帧都是用otsu寻找阈值,于是可以先找到阈值,然后用找到的阈值处理后面的图像。下面这个函数重载了上面的,返回值就是阈值。只做了一点改变

 

我在手的自动检测中使用这个方法,效果很好。

下面是使用上述两个函数的简单的主程序,可以试运行一下,如果处理视频,要保证第一帧时,手要在图像中。

 

 

 

效果图:

1、肤色cb分量

 

2、otsu自适应阈值分割效果

 

3、开运算后效果

  • 2
    点赞
  • 45
    收藏
    觉得还不错? 一键收藏
  • 14
    评论
Otsu阈值分割算法是一种基于图像直方图的自适应阈值分割方法,它可以自动确定分割阈值,使得分割后的两个部分之间的类间方差最大,从而达到最佳分割效果。 以下是Python实现Otsu阈值分割算法的示例代码: ```python import cv2 import numpy as np def otsu_threshold(image): # 计算图像直方图 hist, _ = np.histogram(image, bins=256) # 归一化直方图 hist_norm = hist / float(image.size) # 初始化变量 best_thresh = 0 best_var = 0 w0 = 0 u0 = 0 total_mean = np.mean(image) # 遍历所有阈值 for thresh in range(256): w1 = w0 + hist_norm[thresh] if w1 == 0: continue u1 = (w0 * u0 + thresh * hist_norm[thresh]) / w1 u2 = (total_mean - w1 * u1) / (1 - w1) var_between = w0 * (u0 - total_mean)**2 + w1 * (u1 - total_mean)**2 if var_between > best_var: best_var = var_between best_thresh = thresh w0 = w1 u0 = u1 # 返回最佳阈值 return best_thresh # 读取图像 image = cv2.imread('test.png', 0) # 应用Otsu阈值分割算法 thresh = otsu_threshold(image) binary_image = np.zeros_like(image) binary_image[image > thresh] = 255 # 显示结果 cv2.imshow('Original Image', image) cv2.imshow('Binary Image', binary_image) cv2.waitKey(0) cv2.destroyAllWindows() ``` 其,`otsu_threshold`函数实现Otsu阈值分割算法,输入为灰度图像,输出为最佳阈值。然后,我们可以根据最佳阈值将图像二值化,生成二值化图像。最后,使用OpenCV库的`imshow`函数显示原始图像和二值化图像。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 14
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值