conv_cover.jpeg
开运算和闭运算
腐蚀和膨胀是开运算和闭运算的基础,先腐蚀然后膨胀就是开运算,而先膨胀然后腐蚀就是闭运算。
开运算
先腐蚀后膨胀的过程为开运算 ,看上去把细微连在一起的两块目标分开了。下面图中说明已经足够详细来说明开运算。
erode_dilate.png
对于开运算还有一个很重要的作用,就是消除暗背景下的较亮区域,目的是在不改变黑色台球面积的情况下,消除球上的白色环形区域。
def erode_dilate():
I = cv2.imread("images/eight_ball.jpeg",0)
# 结构元半径
cv2.imshow("I",I)
r = 1
i = 1
MAX_R,MAX_I = 20,20
cv2.namedWindow("morphology",1)
def nothing(*arg):
pass
cv2.createTrackbar("r","morphology",r,MAX_R,nothing)
cv2.createTrackbar("i","morphology",i,MAX_I,nothing)
while(True):
# 显示原图
r = cv2.getTrackbarPos('r','morphology')
i = cv2.getTrackbarPos('i','morphology')
print(r)
s = cv2.getStructuringElement(cv2.MORPH_RECT,(2*r + 1,2*r+1))
d = cv2.morphologyEx(I,cv2.MORPH_OPEN,s,iterations=i)
cv2.imshow("morphology",d)
k = cv2.waitKey(5)
if k==27:
break
cv2.destroyAllWindows()
这个函数的第一个参数表示内核的形状,有三种形状可以选择。
- 矩形:MORPH_RECT;
- 交叉形:MORPH_CROSS;
- 椭圆形:MORPH_ELLIPSE;
第二和第三个参数分别是内核的尺寸以及锚点的位置。一般在调用erode以及dilate函数之前,先定义一个Mat类型的变量来获得
getStructuringElement 函数的返回值: 对于锚点的位置,有默认值Point(-1,-1),表示锚点位于中心点。element 形状唯一依赖锚点位置,其他情况下,锚点只是影响了形态学运算结果的偏移。
代码:
kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE,(11,11))
eight_ball.jpeg
屏幕快照 2019-12-27 下午9.15.36.png
屏幕快照 2019-12-27 下午9.16.14.png
闭运算
与开运算的操作相反,闭运算是对图像先膨胀后腐蚀。先膨胀,再腐蚀,可清除小黑点。
dilate_erode.png
目的是去掉所有骰子上的黑色区域。同样知道膨胀操作可以消除黑色,但是如果是膨胀会增大骰子的面积,而闭运算恰恰可以避免这一点,消除黑色同时不会改变骰子的面积。
def erode_dilate():
I = cv2.imread("images/toss_die.jpeg",0)
# 结构元半径
cv2.imshow("I",I)
r = 1
i = 1
MAX_R,MAX_I = 20,20
cv2.namedWindow("morphology",1)
def nothing(*arg):
pass
cv2.createTrackbar("r","morphology",r,MAX_R,nothing)
cv2.createTrackbar("i","morphology",i,MAX_I,nothing)
while(True):
# 显示原图
r = cv2.getTrackbarPos('r','morphology')
i = cv2.getTrackbarPos('i','morphology')
print(r)
s = cv2.getStructuringElement(cv2.MORPH_RECT,(2*r + 1,2*r+1))
d = cv2.morphologyEx(I,cv2.MORPH_CLOSE,s,iterations=i)
cv2.imshow("morphology",d)
k = cv2.waitKey(5)
if k==27:
break
cv2.destroyAllWindows()
toss_die.jpeg
屏幕快照 2019-12-27 下午9.28.12.png