内容简介:图像处理的过程中,有时候为了加快处理速度,可以容忍一定的信息丢失,这时候就需要用到图像的二值化处理,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 开源的图像处理库,优化移动端图像生成
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
Haskell Programming from first principles
Christopher Allen、Julie Moronuki / 2015 / USD 59.00
I am writing this book because I had a hard time learning Haskell. It doesn't have to be that way. I've spent the last couple years actively teaching Haskell online and in person. Along the way, I ......一起来看看 《Haskell Programming from first principles》 这本书的介绍吧!