欢迎访问 生活随笔!

生活随笔

当前位置: 首页 >

阈值分割之大津法OTSU

发布时间:2024/8/1 77 豆豆
生活随笔 收集整理的这篇文章主要介绍了 阈值分割之大津法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的像素在整幅图的占比为:

w_0 = num0/m*n 同理可得大于阈值T的像素占比: w_1 = num1/m*n w_0+w_1=m*n 此时可以求此阈值下图像的平均灰度:

μ=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=w0w1(μ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的全部内容,希望文章能够帮你解决所遇到的问题。

如果觉得生活随笔网站内容还不错,欢迎将生活随笔推荐给好友。