【python-opencv】图像阈值

【python-opencv】图像阈值,第1张

概述1、简单阈值 在这里,问题直截了当。对于每个像素,应用相同的阈值。如果像素值小于阈值,则将其设置为0,否则将其设置为最大值。函数cv.threshold用于应用阈值。第一个参数是源图像,它应该是灰度图

1、简单阈值

在这里,问题直截了当。对于每个像素,应用相同的阈值。如果像素值小于阈值,则将其设置为0,否则将其设置为最大值。函数cv.threshold用于应用阈值。第一个参数是源图像,它应该是灰度图像。第二个参数是阈值,用于对像素值进行分类。第三个参数是分配给超过阈值的像素值的最大值。OpenCV提供了不同类型的阈值,这由函数的第四个参数给出。通过使用cv.THRESH_BINARY类型。所有简单的阈值类型为:

cv.THRESH_BINARYcv.THRESH_BINARY_INVcv.THRESH_Trunccv.THRESH_TOZEROcv.THRESH_TOZERO_INV

请通过类型的文档来观察区别。

该方法返回两个输出。第一个是使用的阈值,第二个输出是阈值后的图像。

此代码比较了不同的简单阈值类型:

import cv2 as cv numpy as npfrom matplotlib  pyplot as pltimg = cv.imread('gradIEnt.png',0)ret,thresh1 = cv.threshold(img,127,255Original Image',BINARYBINARY_INVTruncTOZEROTOZERO_INV]images = [img,thresh1,thresh2,thresh3,thresh4,thresh5]for i in xrange(6):    plt.subplot(2,3,i+1),plt.imshow(images[i],1)">gray)    plt.Title(Titles[i])    plt.xticks([]),plt.yticks([])plt.show()

注意 为了绘制多个图像,我们使用plt.subplot()函数。请查看matplotlib文档以获取更多详细信息。

结果:

2、自适应阈值

在上一节中,我们使用一个全局值作为阈值。但这可能并非在所有情况下都很好,例如,如果图像在不同区域具有不同的光照条件。在这种情况下,自适应阈值阈值化可以提供帮助。在此,算法基于像素周围的小区域确定像素的阈值。因此,对于同一图像的不同区域,我们获得了不同的阈值,这为光照度变化的图像提供了更好的结果。

除上述参数外,方法cv.adaptiveThreshold还包含三个输入参数:

该adaptiveMethod决定阈值是如何计算的:

cv.ADAPTIVE_THRESH_MEAN_C::阈值是邻近区域的平均值减去常数C。cv.ADAPTIVE_THRESH_GAUSSIAN_C:阈值是邻域值的高斯加权总和减去常数C。

该BLOCKSIZE确定附近区域的大小,C是从邻域像素的平均或加权总和中减去的一个常数。

下面的代码比较了光照变化的图像的全局阈值和自适应阈值:

 pyplot as pltimg=cv.imread(阈值.png)ret,th1 = cv.threshold(img,cv.THRESH_BINARY)th2 = cv.adaptiveThreshold(img,cv.ADAPTIVE_THRESH_MEAN_C,cv.THRESH_BINARY,11,2)th3 = cv.adaptiveThreshold(img,cv.ADAPTIVE_THRESH_GAUSSIAN_C,1)">)Titles = [Global Thresholding (v = 127)Adaptive Mean ThresholdingAdaptive Gaussian Thresholdingin range(4

3、Otsu二值化

在全局阈值化中,我们使用任意选择的值作为阈值。相反,Otsu的方法避免了必须选择一个值并自动确定它的情况。

考虑仅具有两个不同图像值的图像(双峰图像),其中直方图将仅包含两个峰。一个好的阈值应该在这两个值的中间。类似地,Otsu的方法从图像直方图中确定最佳全局阈值。

为此,使用了cv.threshold作为附加标志传递。阈值可以任意选择。然后,算法找到最佳阈值,该阈值作为第一输出返回。

查看以下示例。输入图像为噪点图像。在第一种情况下,采用值为127的全局阈值。在第二种情况下,直接采用Otsu阈值法。在第三种情况下,首先使用5x5高斯核对图像进行滤波以去除噪声,然后应用Otsu阈值处理。了解噪声滤波如何改善结果。

noisy2.png# 全局阈值ret1,th1 = cv.threshold(img,cv.THRESH_BINARY) Otsu阈值ret2,th2 = cv.threshold(img,cv.THRESH_BINARY+cv.THRESH_OTSU) 高斯滤波后再采用Otsu阈值blur = cv.GaussianBlur(img,(5,1)">),0)ret3,th3 = cv.threshold(blur,1)"> 绘制所有图像及其直方图images =Original Noisy ImageHistogramGlobal Thresholding (v=127)"Otsu's Thresholding"Gaussian filtered Image]in xrange(3):    plt.subplot(3,i*3+1),plt.imshow(images[i*3],1)">)    plt.Title(Titles[i*3]),plt.xticks([]),plt.yticks([])    plt.subplot(3,i*3+2),plt.hist(images[i*3].ravel(),256)    plt.Title(Titles[i*3+1)    plt.Title(Titles[i*3+2

Otsu的原理?

由于我们正在处理双峰图像,因此Otsu的算法尝试找到一个阈值(t),该阈值将由关系式给出的加权类内方差最小化。际上,它找到位于两个峰值之间的t值,以使两个类别的差异最小。它可以简单地在Python中实现,如下所示:

img = cv.imread( 寻找归一化直方图和对应的累积分布函数hist = cv.calcHist([blur],[0],None,[256],[0,1)">])hist_norm = hist.ravel()/hist.max()Q = hist_norm.cumsum()bins = np.arange(256)fn_min = np.infthresh = -1in xrange(1,1)">):    p1,p2 = np.hsplit(hist_norm,[i])  概率    q1,q2 = Q[i],Q[255]-Q[i]  对类求和    b1,b2 = np.hsplit(bins,1)"> 权重     寻找均值和方差    m1,m2 = np.sum(p1*b1)/q1,np.sum(p2*b2)/q2    v1,v2 = np.sum(((b1-m1)**2)*p1)/q1,np.sum(((b2-m2)**2)*p2)/q2     计算最小化函数    fn = v1*q1 + v2*if fn < fn_min:        fn_min = fn        thresh = i 使用OpenCV函数找到otsu的阈值ret,otsu = cv.threshold(blur,1)">print( {} {}".format(thresh,ret) )

 

参考:

 http://woshicver.com/FifthSection/4_3_%E5%9B%BE%E5%83%8F%E9%98%88%E5%80%BC/

总结

以上是内存溢出为你收集整理的【python-opencv】图像阈值全部内容,希望文章能够帮你解决【python-opencv】图像阈值所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/1190023.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-06-03
下一篇 2022-06-03

发表评论

登录后才能评论

评论列表(0条)

保存