0x00. 图像二值化
图像二值化就是将图像上的像素点的灰度值设置为0或255,也就是将整个图像呈现出明显的黑白效果。
将256个亮度等级的灰度图像通过适当的阈值选取而获得仍然可以反映图像整体和局部特征的二值化图像。
图像的二值化有利于图像的进一步处理,使图像变得简单,而且数据量减小,能凸显出感兴趣的目标的轮廓。
0x01. 图像二值化处理
在将图像二值化之前需要将其先灰度化,示例代码:
import cv2.cv as cv
image = cv.LoadImage('mao.jpg')
new = cv.CreateImage(cv.GetSize(image), image.depth, 1)
for i in range(image.height):
for j in range(image.width):
new[i,j] = max(image[i,j][0], image[i,j][1], image[i,j][2])
cv.Threshold(new, new, 10, 255, cv.CV_THRESH_BINARY_INV)
cv.ShowImage('a_window', new)
cv.WaitKey(0)
0x02. cv.Threshold
cv.Threshold(src, dst, threshold, maxValue, thresholdType)
函数 cvThreshold 对单通道数组应用固定阈值操作。
该函数的典型应用是对灰度图像进行阈值操作得到二值图像。
参数说明:
src:原始数组 (单通道 , 8-bit of 32-bit 浮点数)。
dst:输出数组,必须与 src 的类型一致,或者为 8-bit。
threshold:阈值
maxValue:使用 CV_THRESH_BINARY 和 CV_THRESH_BINARY_INV 的最大值。
threshold_type:阈值类型
threshold_type=CV_THRESH_BINARY:
如果 src(x,y)>threshold ,dst(x,y) = max_value; 否则,dst(x,y)=0;
threshold_type=CV_THRESH_BINARY_INV:
如果 src(x,y)>threshold,dst(x,y) = 0; 否则,dst(x,y) = max_value.
threshold_type=CV_THRESH_TRUNC:
如果 src(x,y)>threshold,dst(x,y) = max_value; 否则dst(x,y) = src(x,y).
threshold_type=CV_THRESH_TOZERO:
如果src(x,y)>threshold,dst(x,y) = src(x,y) ; 否则 dst(x,y) = 0.
threshold_type=CV_THRESH_TOZERO_INV:如果 src(x,y)>threshold,dst(x,y) = 0 ; 否则dst(x,y) = src(x,y).
对灰度图像利用阈值得到一个二值化的图像,是常最常用的图像处理技术之一。例如,灰度大于127的图像设置为1、小于127的设置为0,这种处理便是固定阈值127的二值化处理。
自适应的二值化处理不同于固定阈值的处理,每个像素的阈值依赖于其邻近的像素灰度,为了得到(x,y)点的阈值T(x,y),我们需要进行以下处理。
在此像素周边选取一个bxb的区域,其中了是用户指定的。
计算此bxb区域的加权平均值。OpenCV提供了两种方法计算此加权均值,一种是算术平均法,另一种是高斯加权平均法,后者要计算均值时距离区域中心越近权重越大。我们将得到的加权均值计为WA(x,y)
将上述加权均值与一固定参数相减得到阈值T(x,y),此固定参数设为param1,则(x,y)点的阈值可以用下式进行计算: T(x,y)=WA(x,y)-param1
这便是得到阈值的过程,下面我们在利用OpenCV库编程实现固定阈值和自适应阈值的方法,我将在IPython环境下实现。
导入必要的模块1
2
1
2
读取图像
读取图像,并把图像转换为灰度图像并显示之。1
2
3
4
5
6
1
2
3
4
5
6
固定阈值二值化
我们首先进行固定阈值二值化处理,固定阈值二值化处理利用cv2.threshold函数,此函数的原型为:1
1
其中:
src 为输入图像;
thresh 为阈值;
maxval 为输出图像的最大值;
type 为阈值的类型;
dst 为目标图像。
此例中我们将阈值设置为50,阈值类型为cv2.THRESH_BINARY,则灰度在大于50的像素其值将设置为255,其它像素设置为0。1
2
3
4
5
1
2
3
4
5
效果如下:
算术平法的自适应二值化
算术平均法的自适应二值化利用cv2.adaptiveThreshold实现,此函数的原型为:1
1
其中:
src 为输入图像;
maxval 为输出图像的最大值;
adaptiveMethod 设置为cv2.ADAPTIVE_THRESH_MEAN_C表示利用算术均值法,设置为cv2.ADAPTIVE_THRESH_GAUSSIAN_C表示用高斯权重均值法;
thresholdType: 阈值的类型;
blockSize: b的值;
C 为从均值中减去的常数,用于得到阈值;
dst 为目标图像。
此例中我们将b设置为5,常数设置为10。1
2
3
4
5
1
2
3
4
5
得到的结果如下图所示:
高斯加权均值法自适应二值化
高斯加权均值法自适应二值化也是利用cv2.adaptiveThreshold, 此函数的原型与上述相同:1
1
其中:
src 为输入图像;
maxval 为输出图像的最大值;
adaptiveMethod 设置为cv2.ADAPTIVE_THRESH_MEAN_C表示利用算术均值法,设置为cv2.ADAPTIVE_THRESH_GAUSSIAN_C表示用高斯权重均值法;
thresholdType: 阈值的类型;
blockSize: b的值;
C 为从均值中减去的常数,用于得到阈值;
dst 为目标图像。1
2
3
4
5
1
2
3
4
5
处理结果如下:
就这么简单,显然自适应方法要比固定阈值的方法效果更好。%pylab
import cv2im = imread("/home/bikz05/Desktop/image.jpg")
im_gray = cv2.cvtColor(im, cv2.COLOR_BGR2GRAY)
axis("off")
title("Input Image")
imshow(im_gray, cmap="gray")
show()cv2.threshold(src, thresh, maxval, type[, dst]) -> retval, dstretval, im_at_fixed = cv2.threshold(im_gray, 50, 255, cv2.THRESH_BINARY)
axis("off")
title("Fixed Thresholding")
imshow(im_at_fixed, cmap = 'gray')
show()cv2.adaptiveThreshold(src, maxValue, adaptiveMethod, thresholdType, blockSize, C[, dst]) -> dstim_at_mean = cv2.adaptiveThreshold(im_gray, 255, cv2.ADAPTIVE_THRESH_MEAN_C, cv2.THRESH_BINARY, 5, 10)
axis("off")
title("Adaptive Thresholding with mean weighted average")
imshow(im_at_mean, cmap = 'gray')
show()cv2.adaptiveThreshold(src, maxValue, adaptiveMethod, thresholdType, blockSize, C[, dst]) -> dstim_at_mean = cv2.adaptiveThreshold(im_gray, 255, cv2.ADAPTIVE_THRESH_MEAN_C, cv2.THRESH_BINARY, 5, 7)
axis("off")
title("Adaptive Thresholding with gaussian weighted average")
imshow(im_at_mean, cmap = 'gray')
show()