一.图像阈值化
图像阈值化(binarization)旨在剔除掉图像中一些低于或高于一定值的像素,从而提取图像中的物体,将图像的背景和噪声区分开来。
灰度化处理后的图像中,每个像素都只有一个灰度值,其大小表示明暗程度。阈值化处理可以将图像中的像素划分为两类颜色,常见的阈值化算法如公式(1)所示:
当某个像素点的灰度gray(i,j)小于阈值t时,其像素设置为0,表示黑色;当灰度gray(i,j)大于或等于阈值t时,其像素值为255,表示白色。
在python的opencv库中,提供了固定阈值化函数threshold()和自适应阈值化函数adaptivethreshold(),将一幅图像进行阈值化处理[3-4]。
二.固定阈值化处理
opencv中提供了函数threshold()实现固定阈值化处理,其函数原型如下:
dst = cv2.threshold(src, thresh, maxval, type[, dst])
– src表示输入图像的数组,8位或32位浮点类型的多通道数
– dst表示输出的阈值化处理后的图像,其类型和通道数与src一致
– thresh表示阈值
– maxval表示最大值,当参数阈值类型type选择cv_thresh_binary或cv_thresh_binary_inv时,该参数为阈值类型的最大值
– type表示阈值类型
其中,threshold()函数不同类型的处理算法如表1所示。
其对应的阈值化描述如图1所示:
阈值化处理广泛应用于各行各业,比如生物学中的细胞图分割、交通领域的车牌识别等。通过阈值化处理将所图像转换为黑白两色图,从而为后续的图像识别和图像分割提供更好的支撑作用。下面详细讲解五种阈值化处理算法。
1.二进制阈值化
该函数的原型为 threshold(gray,127,255,cv2.thresh_binary)。其方法首先要选定一个特定的阈值量,比如127,再按照如下所示的规则进行阈值化处理。
当前像素点的灰度值大于thresh阈值时(如127),其像素点的灰度值设定为最大值(如8位灰度值最大为255);否则,像素点的灰度值设置为0。如阈值为127时,像素点的灰度值为163,则阈值化设置为255;像素点的灰度值为82,则阈值化设置为0。
二进制阈值化处理的python代码如下所示:
# -*- coding: utf-8 -*- # by:eastmount import cv2 import numpy as np #读取图片 src = cv2.imread('luo.png') #灰度图像处理 grayimage = cv2.cvtcolor(src,cv2.color_bgr2gray) #二进制阈值化处理 r, b = cv2.threshold(grayimage, 127, 255, cv2.thresh_binary) #显示图像 cv2.imshow("src", src) cv2.imshow("result", b) #等待显示 cv2.waitkey(0) cv2.destroyallwindows()
输出结果如图2所示,左边是小珞珞的原图,右边是将原图进行二进制阈值化处理的效果图。像素值大于127的设置为255,小于等于127设置为0。
2.反二进制阈值化
该函数的原型为 threshold(gray,127,255,cv2.thresh_binary_inv)。其方法首先要选定一个特定的阈值量,比如127,再按照如下所示的规则进行阈值化处理。
当前像素点的灰度值大于thresh阈值时(如127),其像素点的灰度值设定为0;否则,像素点的灰度值设置为最大值。如阈值为127时,像素点的灰度值为211,则阈值化设置为0;像素点的灰度值为101,则阈值化设置为255。
反二进制阈值化处理的python代码如下所示:
# -*- coding: utf-8 -*- # by:eastmount import cv2 import numpy as np #读取图片 src = cv2.imread('luo.png') #灰度图像处理 grayimage = cv2.cvtcolor(src,cv2.color_bgr2gray) #反二进制阈值化处理 r, b = cv2.threshold(grayimage, 127, 255, cv2.thresh_binary_inv) #显示图像 cv2.imshow("src", src) cv2.imshow("result", b) #等待显示 cv2.waitkey(0) cv2.destroyallwindows()
输出结果如图3所示:
3.截断阈值化
该函数的原型为 threshold(gray,127,255,cv2.thresh_trunc)。图像中大于该阈值的像素点被设定为该阈值,小于或等于该阈值的保持不变,比如127。新的阈值产生规则如下:
比如阈值为127时,像素点的灰度值为167,则阈值化设置为127;像素点的灰度值为82,则阈值化设置为82。截断阈值化处理的python代码如下所示:
# -*- coding: utf-8 -*- # by:eastmount import cv2 import numpy as np #读取图片 src = cv2.imread('luo.png') #灰度图像处理 grayimage = cv2.cvtcolor(src,cv2.color_bgr2gray) #截断阈值化处理 r, b = cv2.threshold(grayimage, 127, 255, cv2.thresh_trunc) #显示图像 cv2.imshow("src", src) cv2.imshow("result", b) #等待显示 cv2.waitkey(0) cv2.destroyallwindows()
输出结果如图4所示,图像经过截断阈值化处理将灰度值处理于0至127之间。
4.阈值化为0
该函数的原型为 threshold(gray,127,255,cv2.thresh_tozero)。按照如下公式对图像的灰度值进行处理。
当前像素点的灰度值大于thresh阈值时(如127),其像素点的灰度值保持不变;否则,像素点的灰度值设置为0。如阈值为127时,像素点的灰度值为211,则阈值化设置为211;像素点的灰度值为101,则阈值化设置为0。
图像阈值化为0处理的python代码如下所示:
# -*- coding: utf-8 -*- # by:eastmount import cv2 import numpy as np #读取图片 src = cv2.imread('luo.png') #灰度图像处理 grayimage = cv2.cvtcolor(src,cv2.color_bgr2gray) #阈值化为0处理 r, b = cv2.threshold(grayimage, 127, 255, cv2.thresh_tozero) #显示图像 cv2.imshow("src", src) cv2.imshow("result", b) #等待显示 cv2.waitkey(0) cv2.destroyallwindows()
输出结果如图5所示,该算法把比较亮的部分不变,比较暗的部分处理为0。
5.反阈值化为0
该函数的原型为 threshold(gray,127,255, cv2.thresh_tozero_inv)。按照如下公式对图像的灰度值进行处理。
当前像素点的灰度值大于thresh阈值时(如127),其像素点的灰度值设置为0;否则,像素点的灰度值保持不变。如阈值为127时,像素点的灰度值为211,则阈值化设置为0;像素点的灰度值为101,则阈值化设置为101。
图像反阈值化为0处理的python代码如下所示:
# -*- coding: utf-8 -*- # by:eastmount import cv2 import numpy as np #读取图片 src = cv2.imread('luo.png') #灰度图像处理 grayimage = cv2.cvtcolor(src,cv2.color_bgr2gray) #二进制阈值化处理 r, b = cv2.threshold(grayimage, 127, 255, cv2.thresh_tozero_inv) #显示图像 cv2.imshow("src", src) cv2.imshow("result", b) #等待显示 cv2.waitkey(0) cv2.destroyallwindows()
输出结果如图6所示:
同样,我们在对民族图腾及图像进行识别和保护时,也需要进行图像阈值化处理。下面代码是对比苗族服饰图像五种固定阈值化处理的对比结果。
# -*- coding: utf-8 -*- # by:eastmount import cv2 import numpy as np import matplotlib.pyplot as plt #读取图像 img=cv2.imread('miao.png') grayimage=cv2.cvtcolor(img,cv2.color_bgr2gray) #阈值化处理 ret,thresh1=cv2.threshold(grayimage,127,255,cv2.thresh_binary) ret,thresh2=cv2.threshold(grayimage,127,255,cv2.thresh_binary_inv) ret,thresh3=cv2.threshold(grayimage,127,255,cv2.thresh_trunc) ret,thresh4=cv2.threshold(grayimage,127,255,cv2.thresh_tozero) ret,thresh5=cv2.threshold(grayimage,127,255,cv2.thresh_tozero_inv) #显示结果 titles = ['gray image','binary','binary_inv','trunc', 'tozero','tozero_inv'] images = [grayimage, 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()
输出结果如图7所示:
三.自适应阈值化处理
前面讲解的是固定值阈值化处理方法,而当同一幅图像上的不同部分具有不同亮度时,上述方法就不在适用。此时需要采用自适应阈值化处理方法,根据图像上的每一个小区域,计算与其对应的阈值,从而使得同一幅图像上的不同区域采用不同的阈值,在亮度不同的情况下得到更好的结果。
自适应阈值化处理在opencv中调用cv2.adaptivethreshold()函数实现,其原型如下所示:
dst = adaptivethreshold(src, maxvalue, adaptivemethod, thresholdtype, blocksize, c[, dst])
– src表示输入图像
– dst表示输出的阈值化处理后的图像,其类型和尺寸需与src一致
– maxvalue表示给像素赋的满足条件的最大值
– adaptivemethod表示要适用的自适应阈值算法,常见取值包括adaptive_thresh_mean_c(阈值取邻域的平均值) 或 adaptive_thresh_gaussian_c(阈值取自邻域的加权和平均值,权重分布为一个高斯函数分布)
– thresholdtype表示阈值类型,取值必须为thresh_binary或thresh_binary_inv
– blocksize表示计算阈值的像素邻域大小,取值为3、5、7等
– c表示一个常数,阈值等于平均值或者加权平均值减去这个常数
当阈值类型thresholdtype为thresh_binary时,其灰度图像转换为阈值化图像的计算公式如下所示:
当阈值类型thresholdtype为thresh_binary_inv时,其灰度图像转换为阈值化图像的计算公式如下所示:
其中,dst(x,y)表示阈值化处理后的灰度值,t(x,y)表示计算每个单独像素的阈值,其取值如下:
当adaptivemethod参数采用adaptive_thresh_mean_c时,阈值t(x,y)为blocksize×blocksize邻域内(x,y)减去参数c的平均值。
当adaptivemethod参数采用adaptive_thresh_gaussian_c时,阈值t(x,y)为blocksize×blocksize邻域内(x,y)减去参数c与高斯窗交叉相关的加权总和。
下面的代码是对比固定值阈值化与自适应阈值化处理的方法。
# -*- coding: utf-8 -*- # by:eastmount import cv2 import numpy as np import matplotlib.pyplot as plt import matplotlib #读取图像 img = cv2.imread('miao.png') #图像灰度化处理 grayimage = cv2.cvtcolor(img, cv2.color_bgr2gray) #固定值阈值化处理 r, thresh1 = cv2.threshold(grayimage, 127, 255, cv2.thresh_binary) #自适应阈值化处理 方法一 thresh2 = cv2.adaptivethreshold(grayimage, 255, cv2.adaptive_thresh_mean_c, cv2.thresh_binary, 11, 2) #自适应阈值化处理 方法二 thresh3 = cv2.adaptivethreshold(grayimage, 255, cv2.adaptive_thresh_gaussian_c, cv2.thresh_binary, 11, 2) #设置字体 matplotlib.rcparams['font.sans-serif']=['simhei'] #显示图像 titles = ['灰度图像', '全局阈值', '自适应平均阈值', '自适应高斯阈值'] images = [grayimage, thresh1, thresh2, thresh3] 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()
输出结果如图8所示,左上角为灰度化处理图像;右上角为固定值全局阈值化处理图像(cv2.threshold);左下角为自适应邻域平均值分割,噪声较多;右下角为自适应邻域加权平均值分割,采用高斯函数分布,其效果相对较好。
四.总结
本文主要讲解了图像阈值化处理知识,调用opencv的threshold()实现固定阈值化处理,调用adaptivethreshold()函数实现自适应阈值化处理。本文知识点将为后续的图像处理提供良好的基础。
以上就是python图像运算之图像阈值化处理详解的详细内容,更多关于python图像阈值化处理的资料请关注其它相关文章!