阈值分割之大津法OTSU
阈值分割之大津法OTSU
- 介绍
- 原理
- 代码实现以及讲解
- 总结
介绍
大津法是一种用来确定图像二值化分割阈值的算法,由日本学者大津与1979年提出,因此被命名为大津法。论文名: N. Otsu, “A threshold selection method from gray-level his-tograms,” IEEE Transactions on Systems, Man and Cybernetics, vol. 9,no. 1, pp. 62–66, 1979.
原理
网上对大津法的原理讲解已经很多了,这里就不再复制粘贴了,说说我的个人理解,不对之处还望指证。大津法的本质就是找到某个灰度值为阈值的时候(寻找的方法是遍历0-255),基于这个阈值得到两个类,计算两个类的类间方差,差值越大那就说明此时选取的阈值是最佳阈值。这么说好像不够直观,还是得贴公式。
设输入图像大小为m行n列(图像类型为灰度图),假设此时选定的阈值为T,则灰度值小于T的像素点个数为num0,大于T的像素点个数为num1。
那么可以计算小于阈值T的像素在整幅图的占比为:
μ=w0∗μ0+w1∗μ1\mu =w0*\mu0+w1*\mu1 μ=w0∗μ0+w1∗μ1
其中μ0,μ1\mu0,\mu1μ0,μ1分别是指两个类分别的平均灰度值(灰度值总和除以像素点个数)。
此时可求得类间方差,计算方法为:
σ2=w0∗(μ0−μ)+w1∗(μ1−μ)\sigma^2=w_0*(\mu0-\mu)+w_1*(\mu1-\mu) σ2=w0∗(μ0−μ)+w1∗(μ1−μ)
联立后化简可以得到:
σ2=w0∗w1(μ0−μ1)\sigma^2=w_0*w_1(\mu0-\mu1) σ2=w0∗w1(μ0−μ1)
当取阈值T使得当前σ2\sigma^2σ2值最大时,为最佳阈值,这是它的计算方式,一般也称为最大类间方差法。下面简单实用python版opencv实现一下,并说一下我在运用过程中得出的该方法的适用场景。
代码实现以及讲解
import cv2 as cv from matplotlib import pyplot as plt#读取图片,我这里原图是灰度图,如果不是的话imread第二个参数选为0(-1,原图,0单通道,1三通道) #或者img = cv.cvtColor(img, cv.COLOR_BGR2GRAY) #如果读入图像有噪声,可以考虑使用滤波器过滤一下 img = cv.imread('test0.img',-1)#返回分割的阈值以及分割后的二值化图像。0,255是返回二值化图的值,大于阈值为255,小于阈值为0 thre_value,thre_img=cv.threshold(img,0,255,cv.THRESH_BINARY+cv.THRESH_OTSU)#我们可以看一下灰度直方图,与输出的阈值对比观察一下 titles = ['Original','Histogram','Ostu_Binary'] images= [img,0,thre_img] for i in range(1):#原图plt.subplot(1,3,i+1)plt.imshow(images[i])plt.title(titles[i])#灰度直方图plt.subplot(1,3,i+2)#先把图像压成一维,然后统计每个像素值个数plt.hist(images[i].ravel())plt.title(titles[i+1])plt.xticks([]),plt.yticks([])#二值化图plt.subplot(1,3,i+3)plt.imshow(images[i+2])plt.title(titles[i+2]) plt.show()总结
根据我的实际使用经验来看,OTSU在前背景比例特别悬殊的时候效果十分不理想,并不好用,比如说如果你想去除脑CT的颅骨,这个方法并不适用,往往找到的值会是脑实质区域的某个像素值。但是在目标区域和背景的比例相近时,效果是客观的。
总结
以上是生活随笔为你收集整理的阈值分割之大津法OTSU的全部内容,希望文章能够帮你解决所遇到的问题。
- 上一篇: DSP技术-2-DSP的C语言同主机C语
- 下一篇: 睡眠分期中的各种特征