内容简介:图像处理的过程中,有时候为了加快处理速度,可以容忍一定的信息丢失,这时候就需要用到图像的二值化处理,opencv提供了一些图像二值化的API简单的二值化处理为,输入图像的灰度图数据,如果像素值大于阈值,则会为其指定一个值(可能为白色),否则将为其指定另一个值(可能为黑色),使用的函数为在简单二值化中,我们使用全局参数作为阈值。但是,假如图像各部分光照情况不同,可能会丢失掉很多信息,得到不好的结果。在这种情况下,我们采用自适应阈值。在该算法中,对图像中的一个小区域进行阈值计算。因此,对于同一图像的不同区域,就
图像处理的过程中,有时候为了加快处理速度,可以容忍一定的信息丢失,这时候就需要用到图像的二值化处理,opencv提供了一些图像二值化的API
1. 简单二值化
简单的二值化处理为,输入图像的灰度图数据,如果像素值大于阈值,则会为其指定一个值(可能为白色),否则将为其指定另一个值(可能为黑色),使用的函数为
double cv::threshold ( InputArray src, //输入的灰度图 OutputArray dst, //输出图 double thresh, //像素值阈值 double maxval, // 当阈值类型为THRESH_BINARY和THRESH_BINARY_INV时的最大值 int type //二值化类型 )
二值化类型
二值化类型图解
示例代码
import cv2 import numpy as np from matplotlib import pyplot as plt img = cv2.imread('test.jpg',0) ret,thresh1 = cv2.threshold(img,127,255,cv2.THRESH_BINARY) ret,thresh2 = cv2.threshold(img,127,255,cv2.THRESH_BINARY_INV) ret,thresh3 = cv2.threshold(img,127,255,cv2.THRESH_TRUNC) ret,thresh4 = cv2.threshold(img,127,255,cv2.THRESH_TOZERO) ret,thresh5 = cv2.threshold(img,127,255,cv2.THRESH_TOZERO_INV) titles = ['Original Image','BINARY','BINARY_INV','TRUNC','TOZERO','TOZERO_INV'] images = [img, thresh1, thresh2, thresh3, thresh4, thresh5] for i in range(6): plt.subplot(2,3,i+1),plt.imshow(images[i],'gray') plt.title(titles[i]) plt.xticks([]),plt.yticks([]) plt.show()
py版本的cv2.threshold返回值有两个,其中第二个参数是本次二值化所使用的阈值(上表的最后两种二值化类型是根据图像计算阈值的),第一个是二值化结果。结果:
2. 自适应二值化
在简单二值化中,我们使用全局参数作为阈值。但是,假如图像各部分光照情况不同,可能会丢失掉很多信息,得到不好的结果。在这种情况下,我们采用自适应阈值。在该算法中,对图像中的一个小区域进行阈值计算。因此,对于同一图像的不同区域,就得到了不同的阈值,对于光照不同的图像,自适应二值化能得到更好的结果。
void cv::adaptiveThreshold ( InputArray src, //8位单通道图像数据 OutputArray dst, //输出图像 double maxValue, //当condition满足时目标像素点的值,非零 int adaptiveMethod, //自适应算法 int thresholdType, //二值化类型,见上一小节中的说明,此处只能取值THRESH_BINARY或THRESH_BINARY_INV int blockSize, //用来计算自适应阈值的块大小,如3、5、7... double C //从平均数或加权平均数中减去的常数。通常情况下,它是正的,但也可以是零,也可以是负的。 )
自适应算法:
|算法名|说明|
|-|-|
blockSize范围内点像素值的平均值 - C|
|ADAPTIVE_THRESH_GAUSSIAN_C |自适应阈值 T(x,y)=(x,y)周边blockSize
blockSize范围内点像素值基于高斯窗口的加权平均数 - C|示例代码:
import cv2 import numpy as np from matplotlib import pyplot as plt def testAdaptiveThreshold(): img = cv2.imread('test.jpg', 0) img = cv2.medianBlur(img, 5) ret, th1 = cv2.threshold(img, 127, 255, cv2.THRESH_BINARY) th2 = cv2.adaptiveThreshold(img, 255, cv2.ADAPTIVE_THRESH_MEAN_C, cv2.THRESH_BINARY, 11, 2) th3 = cv2.adaptiveThreshold(img, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY, 11, 2) titles = ['Original Image', 'Global Thresholding (v = 127)', 'Adaptive Mean Thresholding', 'Adaptive Gaussian Thresholding'] images = [img, th1, th2, th3] for i in range(4): plt.subplot(2, 2, i + 1), plt.imshow(images[i], 'gray') plt.title(titles[i]) plt.xticks([]), plt.yticks([]) plt.show()
效果非常明显,很好的提取了轮廓部分
3. 大津法二值化
大津法二值化,本身也是一种固定阈值的二值化,只不过其阈值是根据图像直方图来计算的,这种方法对于直方图有两个波峰的图像效果比较好。
使用cv2.Threshold()函数,二值化类型传cv2.THRESH_Otsu,阈值传零即可。该算法会自动找到最优阈值,并将找到的阈值作为第二个返回值返回。如果未使用Otsu阈值,则retval与所使用的阈值相同。
下面的示例,输入图像是一个有噪声的图像。第一种情况,使用全局阈值127;第二种情况,直接使用Otsu的阈值;第三种情况,使用5x5高斯核过滤图像以去除噪声,然后应用Otsu阈值。噪声过滤结合大津法二值化,很好的优化了结果。
import cv2 import numpy as np from matplotlib import pyplot as plt def testOtsu(): img = cv2.imread('noisy2.png', 0) # global thresholding ret1, th1 = cv2.threshold(img, 127, 255, cv2.THRESH_BINARY) # Otsu's thresholding ret2, th2 = cv2.threshold(img, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU) # Otsu's thresholding after Gaussian filtering blur = cv2.GaussianBlur(img, (5, 5), 0) ret3, th3 = cv2.threshold(blur, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU) # plot all the images and their histograms images = [img, 0, th1, img, 0, th2, blur, 0, th3] titles = ['Original Noisy Image', 'Histogram', 'Global Thresholding (v=127)', 'Original Noisy Image', 'Histogram', "Otsu's Thresholding", 'Gaussian filtered Image', 'Histogram', "Otsu's Thresholding"] for i in range(3): plt.subplot(3, 3, i * 3 + 1), plt.imshow(images[i * 3], 'gray') plt.title(titles[i * 3]), plt.xticks([]), plt.yticks([]) plt.subplot(3, 3, i * 3 + 2), plt.hist(images[i * 3].ravel(), 256) plt.title(titles[i * 3 + 1]), plt.xticks([]), plt.yticks([]) plt.subplot(3, 3, i * 3 + 3), plt.imshow(images[i * 3 + 2], 'gray') plt.title(titles[i * 3 + 2]), plt.xticks([]), plt.yticks([]) plt.show()
以上所述就是小编给大家介绍的《Opencv图像处理系列(三)——图像二值化》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!
猜你喜欢:- Opencv图像处理系列(六)—— 图像梯度
- Opencv图像处理系列(九)—— 图像轮廓
- Python 图像处理 OpenCV (15):图像轮廓
- Opencv图像处理系列(八)—— 图像金字塔
- Facebook 开源图像处理库 Spectrum,优化移动端图像生成
- Spectrum:Facebook 开源的图像处理库,优化移动端图像生成
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
深入理解OpenCV
[巴西]Daniel Lelis Baggio / 刘波 / 机械工业出版社 / 2014-9 / 59
opencv是最常见的计算机视觉库之一,它提供了许多经过优化的复杂算法。本书对已掌握基本opencv技术同时想提高计算机视觉的实践经验的开发者来讲是一本非常好的书。每章都有一个单独的项目,其背景也在这些章节中进行了介绍。因此,读者可以依次学习这些项目,也可以直接跳到感兴趣的项目进行学习。 《深入理解opencv:实用计算机视觉项目解析》详细讲解9个实用的计算机视觉项目,通过本书的学习,读者可......一起来看看 《深入理解OpenCV》 这本书的介绍吧!