《OpenCV算法精解——基于Python与C++》第七章形态学处理

第七章形态学处理总结

Github地址
形态学处理主要对图像处理,提取高亮区域的暗部,提取暗部区域的高光。

基础构建结构元element:

  • element = cv2.getStructuringElement(shape,ksize)
  • shape: cv2.MORPH_RECT(矩形),cv2.MORPH_ELLIPSEM(椭圆形),cv2.MORPH_CROSS(十字交叉形)

7.1_腐蚀:领域最小灰度做输出灰度。图像亮度降低。亮度区域减小。

  • dst = cv2.erode(src,element,iterations迭代次数)

7.2_膨胀:领域最大灰度做输出灰度。图像亮度提高。亮度区域增加。

  • dst = cv2.dilate(src,element,iterations)

7.3/7.4_开运算&闭运算&白顶帽&黑底帽&形态学梯度

  • 开运算: erode * dilate,消除暗部高亮区域,不改变面积情况下平滑边界

  • 闭运算:dilate * erode,消除高光部分的暗部,多次迭代处理不改变面积情况平滑边界

  • 白顶帽:src - open,得到暗部被消除的高光

  • 黑底帽:src - close,得到高光消除的暗部

  • 形态学梯度:dilate - erode,边缘检测作用

  • dst = cv2.morphologyEx(src,op,element)

    • MORPH_OPEN:开运算
    • MORPH_CLOSE:闭运算
    • MORPH_TOPHAT:顶帽运算
    • MORPH_BLACKHAT:底帽运算
    • MORPH_GRADIENT:梯度运算

7.3还介绍了OpenCV用调节条实时调节结构元半径&迭代次数

7.1_腐蚀erode

本章形态学用来优化分割区域的形状以达到更好的效果。

腐蚀:原理同中值平滑,但选取领域内最小值作为输出灰度。总体亮度平均值会降低。

  • erode(src,element[, dst[, anchor锚点[, iterations迭代次数[, borderType边界扩充类型镜像最好[, borderValue]]]]])

仅需要调节element结构元,与iterations迭代次数即可,其他默认

element为结构元,有三种形状:cv2.MORPH_RECT(矩形),cv2.MORPH_ELLIPSEM(椭圆形),cv2.MORPH_CROSS(十字交叉形)

  • cv2.getStructuringElement(shape, ksize[, anchor])
#-*- coding:utf-8 -*-
import cv2
import matplotlib.pyplot as plt
I = cv2.imread("img2.jpg",0)

#创建3*3,
s3 = cv2.getStructuringElement(cv2.MORPH_RECT,(3,3))
#腐蚀图像,迭代次数默认为1
r3 = cv2.erode(I,s3)
#边界提取
e3 = I - r3

#7*7尺寸结构元
s7 = cv2.getStructuringElement(cv2.MORPH_RECT,(7,7))
r7 = cv2.erode(I,s7)
e7 = I - r7 
#11*11尺寸结构元
s11 = cv2.getStructuringElement(cv2.MORPH_RECT,(11,11))
r11 = cv2.erode(I,s11)
e11 = I - r11 

#显示图像和腐蚀后结果,边界提取效果
for i in range(7):
    titles = ["src","dst3","dst7","dst11","edge3","edge7","edge11"]
    images = [I,r3,r7,r11,e3,e7,e11]
    plt.subplot(2,4,i+1)
    plt.title(titles[i])
    plt.imshow(images[i])
plt.show

《OpenCV算法精解——基于Python与C++》第七章形态学处理_第1张图片
效果很好,随着结构元尺寸增加,白色主体腐蚀越多,结构元形状也形如马赛克被凸显出来。

7.2_膨胀dilate

膨胀与腐蚀相反,选择领域最大灰度值作为输出。输出图像亮度平均值上升,亮部主体尺寸变大。

  • cv2.dilate(src, element[, dst[, anchor[, terations[, borderType[, borderValue]]]]])
#-*- coding:utf-8 -*-
import cv2
import matplotlib.pyplot as plt
I = cv2.imread("img2.jpg",0)
cv2.imshow("I",I)
#结构元半径
r = 1
Max_R = 20
#显示膨胀效果窗口
cv2.namedWindow("dilate",1)
#创建回调函数
def nothing(*arg):
    pass
#创建结构元半径调整条
cv2.createTrackbar("r","dilate",r,Max_R,nothing)
while True:
    #得到当前的r值
    r = cv2.getTrackbarPos('r','dilate')
    #创建结构元
    s = cv2.getStructuringElement(cv2.MORPH_ELLIPSE,(2*r+1,2*r+1))#若为(1,2*r+1),则只有垂直方向发生变化,水平方向不变
    #膨胀图像
    d = cv2.dilate(I,s)
    #显示膨胀效果
    cv2.imshow("dilate",d)
    ch = cv2.waitKey(5)
    #按下Esc退出
    if ch==27:
        break
cv2.destroyAllWindows()

#r=3不错 plt打印一下吧
r1 = 3
s1 = cv2.getStructuringElement(cv2.MORPH_ELLIPSE,(2*r1+1,2*r1+1))
d1 = cv2.dilate(I,s1)
plt.subplot(1,2,1)
plt.imshow(I)
plt.subplot(1,2,2)
plt.imshow(d1)
plt.show()

《OpenCV算法精解——基于Python与C++》第七章形态学处理_第2张图片

7.3_开闭运算

通过将腐蚀与膨胀进行先后组合,也就是开,闭运算。

  • 开运算:先腐蚀后膨胀,消除高亮细节,消除暗处的较亮区域。对较大物体可不改变面积情况下平滑边界。

  • 闭运算:先膨胀后腐蚀,填充亮处的黑色区域。同一个结构元,多次迭代处理可在不改变面积情况下平滑边界。

cv2.morphologyEx(src,op,element[, dst[, anchor[, iterations[, borderType[,borderValue]]]]])
op:

  • MORPH_OPEN:开运算
  • MORPH_CLOSE:闭运算
  • MORPH_TOPHAT:顶帽运算
  • MORPH_BLACKHAT:底帽运算
  • MORPH_GRADIENT:梯度运算

增加调节结构元半径进度条与迭代次数进度条

开运算

#-*- coding:utf-8 -*-
import sys
import cv2
import matplotlib.pyplot as plt
I_open = cv2.imread("open.jpg",0)
cv2.imshow("I_open",I_open)
#结构元半径与迭代次数调节条
r,i=1,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")
    s = cv2.getStructuringElement(cv2.MORPH_RECT,(2*r+1,2*r+1))
    #形态学处理
    d_open = cv2.morphologyEx(I_open,cv2.MORPH_OPEN,s,iterations=i)
    cv2.imshow("morphology",d_open)
    ch = cv2.waitKey(5)
    if ch ==27:
        break
cv2.destroyAllWindows()

#r=3,iterations=5不错
plt.subplot(1,2,1)
plt.imshow(I_open)
plt.subplot(1,2,2)
s = cv2.getStructuringElement(cv2.MORPH_RECT,(2*3+1,2*3+1))
d_open = cv2.morphologyEx(I_open,cv2.MORPH_OPEN,s,iterations=5)
plt.imshow(d_open)
plt.show()

《OpenCV算法精解——基于Python与C++》第七章形态学处理_第3张图片
开运算,暗处中间高亮被消除

#-*- coding:utf-8 -*-
import sys
import cv2
import matplotlib.pyplot as plt
I_close = cv2.imread("open.jpg",0)
cv2.imshow("I_close",I_close)
#结构元半径与迭代次数调节条
r,i=1,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")
    s = cv2.getStructuringElement(cv2.MORPH_RECT,(2*r+1,2*r+1))
    #形态学处理
    d_close = cv2.morphologyEx(I_close,cv2.MORPH_CLOSE,s,iterations=i)
    cv2.imshow("morphology",d_close)
    ch = cv2.waitKey(5)
    if ch ==27:
        break
cv2.destroyAllWindows()

#r=5,i=3不错,打印一下
plt.subplot(1,2,1)
plt.imshow(I_close)
plt.subplot(1,2,2)
s = cv2.getStructuringElement(cv2.MORPH_RECT,(2*5+1,2*5+1))
d_close = cv2.morphologyEx(I_close,cv2.MORPH_CLOSE,s,iterations=3)
plt.imshow(d_close)
plt.show()

《OpenCV算法精解——基于Python与C++》第七章形态学处理_第4张图片
闭运算,高亮中间暗处被消除

7.4_其他形态学操作

其他形态学操作:

  • 白顶帽变换(cv2.MORPH_TOPHAT): 图像减去开运算,得到被消除高亮区域。

  • 黑底帽变换(cv2.MORPH_BLACKHAT):图像减去闭运算,得到被消除的暗部区域。

  • 形态学梯度变换(cv2.MORPH_GRADIENT):膨胀减去腐蚀,得到物体边界。(边缘检测)

import cv2
import matplotlib.pyplot as plt
I = cv2.imread("open.jpg",0)
cv2.imshow("I",I)

r,i = 1,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")
    s = cv2.getStructuringElement(cv2.MORPH_RECT,(2*r+1,2*r+1))
    d_TOPHAT = cv2.morphologyEx(I,cv2.MORPH_TOPHAT,s,iterations=i)
    d_BLACKHAT = cv2.morphologyEx(I,cv2.MORPH_BLACKHAT,s,iterations=i)
    d_GRADIENT = cv2.morphologyEx(I,cv2.MORPH_GRADIENT,s,iterations=i)
    cv2.imshow("TOPHAT",d_TOPHAT)
    cv2.imshow("BLACKHAT",d_BLACKHAT)
    cv2.imshow("GRADIENT",d_GRADIENT)
    ch = cv2.waitKey(5)
    if ch == 27:
        break
cv2.destroyAllWindows()

#r=5,i=3时,顶帽,底帽效果出的好
s = cv2.getStructuringElement(cv2.MORPH_RECT,(2*5+1,2*5+1))
d_TOPHAT = cv2.morphologyEx(I,cv2.MORPH_TOPHAT,s,iterations=3)
d_BLACKHAT = cv2.morphologyEx(I,cv2.MORPH_BLACKHAT,s,iterations=3)
#r=1,i=1时,形态学梯度使边缘出现明显
d_GRADIENT = cv2.morphologyEx(I,cv2.MORPH_GRADIENT,cv2.getStructuringElement(cv2.MORPH_RECT,(2*1+1,2*1+1)),iterations=1)
titles = ["I","TOPHAT","BLACKHAT","GRADIENT"]
images = [I,d_TOPHAT,d_BLACKHAT,d_GRADIENT]
for i in range(4):
    plt.subplot(2,2,i+1)
    plt.title(titles[i])
    plt.imshow(images[i])
plt.show()

《OpenCV算法精解——基于Python与C++》第七章形态学处理_第5张图片
白顶帽显示暗部高亮,黑底部显示高亮暗部。形态学梯度显示边缘检测。

你可能感兴趣的:(OpenCV,opencv,计算机视觉,深度学习,python)