20. Opencv中的形态学处理

什么是形态学? 

  • 基于图像形态处理的一些基本方法,比如识别出图片中杯子的位置,找到物体所在的区域
  • 这些处理方法基本是对二进制图像进行处理,即黑白图像
  • 卷积核决定着图像处理后的效果

形态学处理方法:

  1. 腐蚀与膨胀,腐蚀是将一个区域变小,膨胀是变大
  2. 开运算,即先腐蚀后膨胀,最后一个动作为放大,因此称为开运算
  3. 闭运算,先膨胀后腐蚀,最后一个动作为缩小,因此称为闭运算
  4. 顶帽运算
  5. 黑帽运算

图像二值化

将图像的每个像素变成两种值,如0,255

全局二值化:画一条线,所有的像素均与这条线进行对比,低于为0,高于为255

局部二值化:把图形分为不同的区域,在每个区域内再进行二值化处理,主要针对光线不好的图像。

全局二值化threshold API

threshold(img, thresh, maxVal, type)

img 灰度图像

thresh 阈值

maxVal 超过阈值,替换成maxVal

type

import cv2
import numpy as np

img1 = cv2.imread('E:\\112.png')
img2 = cv2.cvtColor(img1,cv2.COLOR_BGR2GRAY) #将图像转为灰度图

ret, dst = cv2.threshold(img2, 125, 255, cv2.THRESH_BINARY)

cv2.imshow('img1',img1)
cv2.imshow('img2',img2)
cv2.imshow('dst',dst)

cv2.waitKey(0)

阙值类型

 自适应阙值二值化

由于光照不均匀以及阴影的存在,只有一个阙值会使得在阴影处的白色被二值化成黑色,此时适合采用  自适应阙值二值化

自适应阙值二值化 API

adaptiveThreshold(img, maxVal, adaptiveMethod, type, blockSize, C)

maxVal        转换的目标最大值

adaptiveMethod        计算阙值的方法

blockSize        要计算的区域大小,若想计算的比较精准,则选择小的区域,若想计算的速度快一些,则把计算的区域设较大一点

type  共有两种:

①THRESH_BINARY

②THRESH_BINARY_INV

C        常量,应从计算出的平均值或加权平均值中减去,一般设为0即可

adaptiveMethod 计算阈值的方法

  • ADAPTIVE_THRESH_MEAN_C        计算临近区域的平均值
    • ADAPTIVE_THRESH_GAUSSIAN_C                高斯窗口加权平均值

一般情况下,选择高斯窗口加权平均值

import cv2
from cv2 import ADAPTIVE_THRESH_GAUSSIAN_C
import numpy as np

img1 = cv2.imread('E:\\113.jpg')
img2 = cv2.cvtColor(img1,cv2.COLOR_BGR2GRAY) #将图像转为灰度图

# 全局二值化
# ret, dst = cv2.threshold(img2, 125, 255, cv2.THRESH_BINARY)

#自适应二值化
dst  = cv2.adaptiveThreshold(img2, 255, ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY,3,0)

cv2.imshow('img1',img1)
cv2.imshow('img2',img2)
cv2.imshow('dst',dst)

cv2.waitKey(0)

 Opencv腐蚀

腐蚀的原理

 

左上角红色的为一个卷积核(所有元素全为1),进行卷积时,只有在所有像素大于1时才为1,其他为0,中心点像素变化

腐蚀效果图:

 腐蚀API

erode(img, kernel, iterations=1)

注:卷积核越大,腐蚀的效果越明显

iterations = 1 腐蚀的次数

#腐蚀
kernel = np.ones((3,3), np.uint8)
cv2.erode(img2, kernel,iterations=1 )

经过腐蚀后,图像变小

 卷积核的类型,获取形态学卷积核

getStructuringElement(type, size)

通过该API可以获取一个卷积核,type为卷积核的类型

size值为:(3,3)、(5,5)......只能为奇数,最小3*3

卷积核的类型

  • MORPH_RECT               矩形,全1,常用
  • MORPH_ELLIPSE          椭圆形,四个角为0,其他地方为1
  • MORPH_CROSS            交叉形,十字形,横竖为1,其他为0
kernel = cv2.getStructuringElement(cv2.MORPH_RECT,(3,3))
print(kernel)

选择合适的卷积核和size进行腐蚀

Opencv膨胀

 A与B进行卷积,保证卷积核的中心锚点不为0,经过卷积后,它的周边不论是0还是非0,都变为了非0值。卷积核越大膨胀速度越快,膨胀效果如下:

 膨胀API

dilate(img, kernel, iterations = 1)

参数含义与腐蚀类似

kernel = cv2.getStructuringElement(cv2.MORPH_RECT,(3,3))
# 膨胀
dst = cv2.dilate(img1, kernel, iterations=1)

注:腐蚀之后,再膨胀无法恢复为原图像,是因为腐蚀对原图像的破坏较大

卷积核越大,破坏越大

问题

1.如果是白底黑字,进行腐蚀与膨胀后会怎样?

在对图像边缘检测之后,再对检测后的图像进行一些操作后可以令待检测图像的特征更加突出,以白底黑字为例,腐蚀操作会腐蚀白色亮区,令黑字更加明显膨胀操作则会膨胀白色亮区,令黑字细小,从上篇文章最终显示的边缘处理后的图像可知,检测出的边缘以白边描绘,因此,为了增加车牌特征,可以使用膨胀函数,而图像的二值化可以使处理后的图像只存在黑白两种颜色,便于计算机检测识别,提高识别效率。

2. 卷积核是否可以设置为全0?

将所有的参数初始化为0之后,这一层的输出也必然是0,那么在下一层当中,不管卷积核是什么样的参数分布,经过卷积之后的结果也还是0,由于偏置默认是0,所以输出依然是0,因此这种情况下,整个网络的输出就是0。考虑到网络的数据需要在反向传播的过程中进行更新,而计算参数的梯度以及前行传递的误差的过程中需要使用每一层的输入(而大部分层的输入都是0),因此,无法进行梯度的更新。

开运算

开运算 = 腐蚀 +膨胀

 开运算,去除图像周围的噪点,因为进行腐蚀时,选择合适的卷积核,白色的点(周围是黑色的)会被当作边缘点,经过腐蚀后整个字符会小一圈,然后再膨胀

开运算API

morphologyEx(img, Morph_OPEN,kernel)

Morph_OPEN        开运算为OPEN,闭运算为CLOSE

kernel        卷积核的大小,对于大的噪点,一般选择比较大的卷积核

# 开运算
dst = cv2.morphologyEx(img1, cv2.MORPH_OPEN, kernel)

调用这一个API就可以实现  腐蚀与膨胀的操作

闭运算

闭运算 = 膨胀 + 腐蚀

解决的问题如果字符内部有很多噪点,可以用闭运算去除噪声,开运算是去除外部噪声

原理:膨胀时,如果中心点为1,则会把周围点都变为1,因为黑点旁边为白色,所以会把周边都变为白色,然后再经过腐蚀变为与原图一致大小

闭运算API

morphologyEx(img, Morph_CLOSE,kernel)

                  

在字符内部还有一些比较暗的小点,可以通过调整卷积核的大小进一步调整闭运算效果

开运算与闭运算记法:记最后一个动作,最后一个动作为膨胀则为开运算,最后一个动作为腐蚀则为闭运算。

形态学梯度

梯度 = 原图 - 腐蚀

求边缘的方法:高通滤波,Canny阙值计算、形态学梯度

梯度API

morphologyEx(img,MORPH_GRADIENT,kernel)

该命令与开运算  闭运算类似

计算的效果与kernel有关,kernel小则腐蚀的少一些,kernel大则腐蚀的多一点,此时原图- 腐蚀,得到的边缘不会太明显

# 梯度运算
dst = cv2.cv2.morphologyEx(img1, cv2.MORPH_GRADIENT, kernel)

   kernel为7*7

        kernel为3*3

顶帽运算

顶帽运算 = 原图 - 开运算

 通过顶帽运算可以把大的白块去掉,留下两个小的白块

顶帽API

morphologyEx(img, MORPH_TOPHAT, kernel)

# 顶帽运算
dst = cv2.morphologyEx(img1, cv2.MORPH_TOPHAT, kernel)

 处理效果与卷积核大小有关

黑帽运算

黑帽运算 = 原图 - 闭运算

黑帽运算求得的是在一块区域中小的噪点

效果:可以将图中的噪点取出来

 黑帽API

morphologyEx(img, MORPH_BLACKHAT, kernel)

 处理效果与卷积核大小有关

总结

  1. 开运算:先腐蚀再膨胀,去除大图形的小图形
  2. 闭运算:先膨胀再腐蚀,去除大图形的小图形
  3. 梯度:求图形的边缘
  4. 顶帽:原图减开运算,得到大图形的小图形
  5. 黑帽:原图减闭运算,得到大图形的小图形

MorphologyType

所有操作的基础都是腐蚀和膨胀

猜你喜欢

转载自blog.csdn.net/qq_45355603/article/details/125263527