Python-OpenCV之形态学处理(腐蚀,膨胀,开运算和闭运算,顶帽变换和底帽变换)

腐蚀

OpenCV函数原型

cv2.erode(src, element[, dst[, anchor[, iterations[, borderType[, borderValue]]]]])

参数解释

src

输入的原图片

element

结构元

anchor结构元的锚点
iterations腐蚀操作的次数
borderType边界扩充类型
boderValue边界扩充值

 与卷积操作类似,对于边界处的像素的领域有可能会超出图像边界,所以需要扩充图像边界,边界扩充类型中镜像扩充操作效果最好。

其中,参数element可由OpenCV提供的下列函数获取

cv2.getStructuringElement(shape, ksize[, anchor])

 参数解释

shape

MORPH_RECT: 产生矩形的结构元

MORPH_ELLIPSEM: 产生椭圆形的结构元

MORPH_CROSS: 产生十字交叉形的结构元

ksize结构元的尺寸
anchor结构元的锚点

代码示例

import cv2 as cv
import numpy as np

# 读入图片
src = cv.imread('test.jpg', flags=0)
# 添加说明文字
ori = src.copy()
cv.putText(ori, "Original Image", (580, 100), cv.FONT_HERSHEY_COMPLEX, 2.0, (150, 10, 0), 5)

# 生成卷积核
kernel = cv.getStructuringElement(cv.MORPH_RECT, (3, 3))
# 进行腐蚀处理
erosion = cv.erode(src, kernel, iterations=3)
# 添加说明文字
cv.putText(erosion, "Eroded Image", (580, 100), cv.FONT_HERSHEY_COMPLEX, 2.0, (150, 10, 0), 5)

# 将原图片与腐蚀处理后的图片拼接起来
show = np.hstack([ori, erosion])
# 显示图片
cv.namedWindow('result', cv.WINDOW_NORMAL)
cv.imshow('result', show)

cv.waitKey()
cv.destroyAllWindows()

处理效果

膨胀

OpenCV函数原型

cv2.dilate(src, element[, dst[, anchor[, iterations[, borderType[, borderValue]]]]])

参数解释

src

输入的原图片

element

结构元

anchor结构元的锚点
iterations腐蚀操作的次数
borderType边界扩充类型
boderValue边界扩充值

代码示例

import cv2 as cv
import numpy as np

# 读入原图片
src = cv.imread('test.jpg', flags=0)
# 添加说明文字
ori = src.copy()
cv.putText(ori, "Original Image", (580, 100), cv.FONT_HERSHEY_COMPLEX, 2.0, (150, 10, 0), 5)

# 生成卷积核
kernel = cv.getStructuringElement(cv.MORPH_RECT, (3, 3))
# 进行腐蚀处理
erosion = cv.dilate(src, kernel, iterations=3)
# 添加说明文字
cv.putText(erosion, "Dilated Image", (580, 100), cv.FONT_HERSHEY_COMPLEX, 2.0, (150, 10, 0), 5)

# 将原图片与腐蚀处理后的图片拼接起来
show = np.hstack([ori, erosion])
# 显示图片
cv.namedWindow('result', cv.WINDOW_NORMAL)
cv.imshow('result', show)
cv.imwrite('DilatedImage.jpg', show)

cv.waitKey()
cv.destroyAllWindows()

处理效果

其他形态学处理

OpenCV函数原型

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

开运算和闭运算均是腐蚀和膨胀的组合,而顶帽变换和底帽变换是分别以开运算和闭运算为基础的。这四个操作都可直接使用OpenCV提供的上述API来完成

参数解释

src输入矩阵
op

形态学处理的各种运算,值的设置如下:

MORPH_OPEN:开运算

MORPH_CLOSE:比运算

MORPH_GRADIENT:形态梯度

MORPH_TOPHAT:顶帽运算

MORPH_BLACKHAT:底帽运算

elememt

结构元

anchor结构元的锚点
iterations迭代次数

开运算和闭运算

开运算

先腐蚀,后膨胀

主要用于消除亮度较高的细小区域,在纤细点处分离物体,对于较大物体,可以在不明显改变其面积的情况下平滑其边界。

代码示例

import cv2 as cv

src = cv.imread('test2.jpg', flags=0)

# 结构元初始半径,最大半径
r, MAX_R = 0, 20
# 初始迭代次数,最大迭代次数
i, MAX_I = 0, 20

# 创建窗口
cv.namedWindow('morphology')


# 设置回调函数
def nothing(*args):
    pass


# 创建滑动条,分别为半径和迭代次数
cv.createTrackbar('r', 'morphology', r, MAX_R, nothing)
cv.createTrackbar('i', 'morphology', i, MAX_I, nothing)

while True:
    # 得到进度条上当前的r值
    r = cv.getTrackbarPos('r', 'morphology')
    # 得到进度条上当前的i值
    i = cv.getTrackbarPos('i', 'morphology')
    # 创建结构元
    kernel = cv.getStructuringElement(cv.MORPH_RECT, (2 * r + 1, 2 * r + 1))
    # 形态学处理:开运算
    result = cv.morphologyEx(src, cv.MORPH_OPEN, kernel, iterations=i)
    # 显示效果
    cv.imshow('morphology', result)
    # 按Esc退出
    ch = cv.waitKey(5)
    if ch == 27:
        break
cv.destroyAllWindows()

处理效果

闭运算

先膨胀,后腐蚀

主要用于填充白色物体内细小黑色空洞的区域,连接临近物体,同一个结构元,多次迭代处理,也可以在不明显改变其面积的情况下平滑其边界。

代码示例

import cv2 as cv

src = cv.imread('test2.jpg', flags=0)

# 结构元初始半径,最大半径
r, MAX_R = 0, 20
# 初始迭代次数,最大迭代次数
i, MAX_I = 0, 20

# 创建窗口
cv.namedWindow('morphology')


# 设置回调函数
def nothing(*args):
    pass


# 创建滑动条,分别为半径和迭代次数
cv.createTrackbar('r', 'morphology', r, MAX_R, nothing)
cv.createTrackbar('i', 'morphology', i, MAX_I, nothing)

while True:
    # 得到进度条上当前的r值
    r = cv.getTrackbarPos('r', 'morphology')
    # 得到进度条上当前的i值
    i = cv.getTrackbarPos('i', 'morphology')
    # 创建结构元
    kernel = cv.getStructuringElement(cv.MORPH_RECT, (2 * r + 1, 2 * r + 1))
    # 形态学处理:闭运算
    result = cv.morphologyEx(src, cv.MORPH_CLOSE, kernel, iterations=i)
    # 显示效果
    cv.imshow('morphology', result)
    # 按Esc退出
    ch = cv.waitKey(5)
    if ch == 27:
        break
cv.destroyAllWindows()

处理效果

顶帽变换和底帽变换

顶帽变换

原图像减去开运算结果

开运算可以消除暗背景下的较亮区域,所以顶帽变换可以得到原图中灰度较亮的区域。顶帽变换的一个很重要的作用就是校正不均匀光照

代码示例

import cv2 as cv

src = cv.imread('test2.jpg', flags=0)

# 结构元初始半径,最大半径
r, MAX_R = 0, 20
# 初始迭代次数,最大迭代次数
i, MAX_I = 0, 20

# 创建窗口
cv.namedWindow('morphology')


# 设置回调函数
def nothing(*args):
    pass


# 创建滑动条,分别为半径和迭代次数
cv.createTrackbar('r', 'morphology', r, MAX_R, nothing)
cv.createTrackbar('i', 'morphology', i, MAX_I, nothing)

while True:
    # 得到进度条上当前的r值
    r = cv.getTrackbarPos('r', 'morphology')
    # 得到进度条上当前的i值
    i = cv.getTrackbarPos('i', 'morphology')
    # 创建结构元
    kernel = cv.getStructuringElement(cv.MORPH_RECT, (2 * r + 1, 2 * r + 1))
    # 形态学处理:顶帽处理
    result = cv.morphologyEx(src, cv.MORPH_TOPHAT, kernel, iterations=i)
    # 显示效果
    cv.imshow('morphology', result)
    # 按Esc退出
    ch = cv.waitKey(5)
    if ch == 27:
        break
cv.destroyAllWindows()

处理效果

底帽变换

原图片减去闭运算结果

闭运算可以删除亮度较高背景下的较暗区域,所以底帽变换可以得到原图片中灰度较暗的区域,故而又称黑帽变换。 

代码示例

import cv2 as cv

src = cv.imread('test2.jpg', flags=0)

# 结构元初始半径,最大半径
r, MAX_R = 0, 20
# 初始迭代次数,最大迭代次数
i, MAX_I = 0, 20

# 创建窗口
cv.namedWindow('morphology')


# 设置回调函数
def nothing(*args):
    pass


# 创建滑动条,分别为半径和迭代次数
cv.createTrackbar('r', 'morphology', r, MAX_R, nothing)
cv.createTrackbar('i', 'morphology', i, MAX_I, nothing)

while True:
    # 得到进度条上当前的r值
    r = cv.getTrackbarPos('r', 'morphology')
    # 得到进度条上当前的i值
    i = cv.getTrackbarPos('i', 'morphology')
    # 创建结构元
    kernel = cv.getStructuringElement(cv.MORPH_RECT, (2 * r + 1, 2 * r + 1))
    # 形态学处理:底帽处理
    result = cv.morphologyEx(src, cv.MORPH_BLACKHAT, kernel, iterations=i)
    # 显示效果
    cv.imshow('morphology', result)
    # 按Esc退出
    ch = cv.waitKey(5)
    if ch == 27:
        break
cv.destroyAllWindows()

处理效果

形态学梯度

膨胀结果减去腐蚀结果

膨胀是取领域内的最大值从而增大高亮度区域的面积;腐蚀是取领域内的最小值,从而减小高亮度区域的面积。所以形态学梯度的处理结果是图像中物体的边界。

代码示例

import cv2 as cv

src = cv.imread('test2.jpg', flags=0)

# 结构元初始半径,最大半径
r, MAX_R = 0, 20
# 初始迭代次数,最大迭代次数
i, MAX_I = 0, 20

# 创建窗口
cv.namedWindow('morphology')


# 设置回调函数
def nothing(*args):
    pass


# 创建滑动条,分别为半径和迭代次数
cv.createTrackbar('r', 'morphology', r, MAX_R, nothing)
cv.createTrackbar('i', 'morphology', i, MAX_I, nothing)

while True:
    # 得到进度条上当前的r值
    r = cv.getTrackbarPos('r', 'morphology')
    # 得到进度条上当前的i值
    i = cv.getTrackbarPos('i', 'morphology')
    # 创建结构元
    kernel = cv.getStructuringElement(cv.MORPH_RECT, (2 * r + 1, 2 * r + 1))
    # 形态学处理:形态梯度
    result = cv.morphologyEx(src, cv.MORPH_GRADIENT, kernel, iterations=i)
    # 显示效果
    cv.imshow('morphology', result)
    # 按Esc退出
    ch = cv.waitKey(5)
    if ch == 27:
        break

cv.destroyAllWindows()

处理效果

 

  • 12
    点赞
  • 69
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值