OpenCV-Python开发指南(16)---自适应阈值处理与Otsu处理

为什么需要自适应阈值处理

对于色彩均衡的图像来说,直接使用一个阈值就能完成对图像的阈值化处理。但是,有时候图像的色彩是不均衡的,此时如果只用一个阈值,就无法得到清晰有效的阈值分割的图像,所以,我们需要采用自适应阈值处理。

简单的说,自适应阈值处理是通过计算每个像素点轴为临近区域的加权平均值获得阈值,并使用该阈值对当前像素点进行处理。

其优点是能够更好的处理明暗差异较大的图像。

adaptiveThreshold

在OpenCV中,它给我们提供了cv2.adaptiveThreshold()函数来实现自适应阈值处理,定义如下:

def adaptiveThreshold(src, maxValue, adaptiveMethod, thresholdType, blockSize, C, dst=None):

src:需要处理的原始图像

maxValue:代表最大值

adaptiveMethod:自适应的方法

thresholdType:代表阈值处理方式,该值必须是cv2.THRESH_BINARY或者cv2.THRESH_BINARY_INV中的一个

blockSize:块的大小,表示一个像素在计算其阈值时所使用的邻域尺寸,通常为3,5,7等

C:常量

通过参数,我们可以肯定在处理图像的时候,我们需要提供一个自定义的阈值处理方法。而OpenCV给我们提供了两种:cv2.ADAPTIVE_THRESH_MEAN_C与cv2.ADAPTIVE_THRESH_GAUSSINA_C。它们都是逐个像素的计算自适应阈值,自适应阈值等于每个像素由参数blockSize所指定的邻域的加权平均值减去常量C。

其中,两种不同的方法计算邻域的加权平均值不同:

(1)cv2.ADAPTIVE_THRESH_MEAN_C:邻域所有像素点的权重值是一致的

(2)cv2.ADAPTIVE_THRESH_GAUSSINA_C:与邻域各个像素点到中心点的距离有关,通过高斯方程得到各个点的权重值

下面我们分别实现看看其效果如何,具体代码如下:

import cv2

img = cv2.imread("4.jpg", 0)
t, result_img = cv2.threshold(img, 127, 255, cv2.THRESH_BINARY)
atmc_img=cv2.adaptiveThreshold(img,255,cv2.ADAPTIVE_THRESH_MEAN_C,cv2.THRESH_BINARY,5,3)
atgc_im=cv2.adaptiveThreshold(img,255,cv2.ADAPTIVE_THRESH_GAUSSIAN_C,cv2.THRESH_BINARY,5,3)
cv2.imshow("img", img)
cv2.imshow("result_img", result_img)
cv2.imshow("atmc_img", atmc_img)
cv2.imshow("atgc_im", atgc_im)
cv2.waitKey()
cv2.destroyAllWindows()

自适应

Otsu处理

在使用函数cv2.threshold()函数进行阈值处理时,需要一个自定义的阈值。通常情况下,图像是色彩均衡的,这个时候,直接设置阈值处理是比较合适的。

但是实际处理的图像往往更加的复杂,不太可能直接观察出阈值,如果一个个取尝试,无疑是一个巨大的工作量。

而Otsu方法能够根据当前图像给出的最佳的类间分割阈值。简单的说,Otsu方法会遍历所有可能阈值,从而找到最佳的阈值。

在cv2.threshold()函数中,它给我们提供了一个type参数,传递给它cv2.THRESH_OTSU,即可实现Otsu方法的阈值分割。

需要注意的是,在使用Otsu方法时,要把阈值设为0。此时的cv2.threshold()会自动寻找最优阈值,并将该阈值返回。如上面代码中有个t,返回的就是阈值。

下面,我们来通过Otsu处理实现,具体代码如下所示:

import cv2

img = cv2.imread("4.jpg", 0)
t1, result_img = cv2.threshold(img, 127, 255, cv2.THRESH_BINARY)
t2, otsu_img = cv2.threshold(img, 0, 255, cv2.THRESH_BINARY+cv2.THRESH_OTSU)
cv2.imshow("img", img)
cv2.imshow("result_img", result_img)
print(t2)
cv2.imshow("otsu_img", otsu_img)
cv2.waitKey()
cv2.destroyAllWindows()

运行之后,效果如下所示:
阈值处理
可以看到,该图像最佳的二值化阈值处理阈值是145。

猜你喜欢

转载自blog.csdn.net/liyuanjinglyj/article/details/113807739