Python OpenCV学习之图像形态学
背景
形态学处理方法是基于对二进制图像进行处理的,卷积核决定图像处理后的效果;形态学的处理哦本质上相当于对图像做前处理,提取出有用的特征,以便后续的目标识别等任务;
一、图像二值化
定义:将图像的每个像素变成两种值,如0和255;
全局二值化的函数原型:
threshold(img,thresh,maxval,type)
-
img
:最好是灰度图像 -
thresh
:阈值 -
maxval
:超过阈值,替换为maxval -
type
:有几种类型,thresh_binary为二值化的类型
案例代码:
img = cv2.imread('1.jpg') img = cv2.cvtcolor(img, cv2.color_bgr2gray) ret, dst = cv2.threshold(img, 100, 255, cv2.thresh_binary) cv2.imshow('org', img) cv2.imshow('dst', dst) cv2.waitkey(0)
关于type类型,可查看下图:
二、自适应阈值
解决的问题:由于光照不均匀以及阴影的存在,只有一个阈值会使得在阴影处的白色被二值化成黑色;
若采用全局二值化,在有阴影的图片中,阴影信息会丢失,如下图:
当阈值设置较高时,会出现部分阴影信息丢失,如果需要不断尝试找到合适阈值是一件耗时的事情,因此就有了自适应阈值的方法;
自适应阈值函数原型:
adaptivethreshold(img,maxval,adaptivemethod,,type,blocksize, c)
-
adaptivemethod
:计算阈值的方法; -
blocksize
:邻近区域的大小; -
c
:常量,应从计算出的平均值或加权平均值中减去,一般设置为0;
计算阈值主要有两种两种方法:
① adaptive_thresh_mean_c:计算邻近区域的平均值;(根据blocksize大小做平均滤波)
② adaptive_thresh_gaussian_c:高斯窗口加权平均值;(根据blocksize大小做高斯滤波)
代码案例:
img = cv2.imread('new.jpg') img = cv2.cvtcolor(img, cv2.color_bgr2gray) dst = cv2.adaptivethreshold(img, 255, cv2.adaptive_thresh_gaussian_c, cv2.thresh_binary_inv, 11, 0) cv2.imshow('org', img) cv2.imshow('dst', dst) cv2.waitkey(0)
可以看出,虽然信息成功提取出来,但背景的噪点过多,后续会加以处理;
三、腐蚀
本质卷积核的值全为1,可通过下图简单理解其原理:
函数原型:
erode(img,kernel,iterations=1)
iterations
:执行的次数;
代码案例:
img = cv2.imread('./j.png') kernel = np.ones((3, 3), np.uint8) dst = cv2.erode(img, kernel, 1) cv2.imshow('org', img) cv2.imshow('dst', dst) cv2.waitkey(0)
上图为腐蚀后的结果,明显白色区域变小了,如果增大卷积核或增加腐蚀次数会使得腐蚀效果更明显;
四、卷积核获取
函数原型:
getstructuringelement(type,size)
size
一般设置成(3,3)或(5,5)这样;
type
类型:
morph_rect:矩形形状的卷积核;
morph_ellipse:椭圆形状卷积核;
morph_cross:十字架形状卷积核;
腐蚀中的全为1的卷积核可以通过这个函数构造:
kernrl = cv2.getstructuringelement(cv2.morph_rect, (3, 3))
相比于用numpy构造更好;
五、膨胀
膨胀和腐蚀相反,其原理是卷积核中间不为0,则整个卷积核区域的值都为1,如下图:
函数原型:
dilate(img,kernel,iterations=1)
代码案例:
img = cv2.imread('./j.png') kernel = np.ones((7, 7), np.uint8) dst = cv2.dilate(img, kernel, 1) cv2.imshow('org', img) cv2.imshow('dst', dst) cv2.waitkey(0)
本次采用7x7的卷积核,所以效果会比较明显一些;
六、开运算
本质:先腐蚀,后膨胀;
函数原型:
morphologyex(img,cv2.morph_open,kernel)
代码案例:
img = cv2.imread('./dotj.png') kernel = cv2.getstructuringelement(cv2.morph_rect, (7, 7)) dst = cv2.morphologyex(img, cv2.morph_open, kernel) cv2.imshow('org', img) cv2.imshow('dst', dst) cv2.waitkey(0)
从图中可看出,开运算很好的解决了小的噪点,也就是背景噪点去除;
七、闭运算
本质:先膨胀,后腐蚀;
函数原型等同于开运算,其中的类型进行修改即可;
代码案例:
img = cv2.imread('./dotinj.png') kernel = cv2.getstructuringelement(cv2.morph_rect, (7, 7)) dst = cv2.morphologyex(img, cv2.morph_close, kernel) cv2.imshow('org', img) cv2.imshow('dst', dst) cv2.waitkey(0)
中间还是有一些噪点没有完全消除,可以调整卷积核大小,将卷积核调大,可以得到更好的效果;
八、形态学梯度
本质:梯度 = 原图 - 腐蚀
函数还是morphologyex,其中类型为morph_gradient;
代码案例:
img = cv2.imread('./j.png') kernel = cv2.getstructuringelement(cv2.morph_rect, (3, 3)) dst = cv2.morphologyex(img, cv2.morph_gradient, kernel) cv2.imshow('org', img) cv2.imshow('dst', dst) cv2.waitkey(0)
可以看出来腐蚀的部分,也相当于提取了边缘;
九、顶帽运算
本质:顶帽 = 原图 - 开运算
函数还是morphologyex,其中类型为morph_tophat;
代码案例:
img = cv2.imread('./tophat.png') kernel = cv2.getstructuringelement(cv2.morph_rect, (19, 19)) dst = cv2.morphologyex(img, cv2.morph_tophat, kernel) cv2.imshow('org', img) cv2.imshow('dst', dst) cv2.waitkey(0)
十、黑帽运算
本质:黑帽 = 原图 - 闭运算
函数还是morphologyex,其中类型为morph_blackhat;
代码案例:
img = cv2.imread('./dotinj.png') kernel = cv2.getstructuringelement(cv2.morph_rect, (7, 7)) dst = cv2.morphologyex(img, cv2.morph_blackhat, kernel) cv2.imshow('org', img) cv2.imshow('dst', dst) cv2.waitkey(0)
总结
开运算:先腐蚀再膨胀,去除大图形外的小图形;
闭运算:先膨胀再腐蚀,去除大图形内的小图形;
梯度:求图形的边缘;
顶帽:原图减开运算,得到大图形外的小图形;
黑帽:原图减闭运算,得到大图形内的小图形;
以上就是python opencv学习之图像形态学的详细内容,更多关于python opencv图像形态学的资料请关注其它相关文章!