首页 最新 热门 推荐

  • 首页
  • 最新
  • 热门
  • 推荐

opencv进阶学习笔记13:图像形态学操作大全(膨胀,腐蚀,开闭,黑帽,顶帽,梯度)python版

  • 23-09-22 20:43
  • 2228
  • 11178
blog.csdn.net

基础版学习笔记:
python3+opencv学习笔记汇总目录(适合基础入门学习)
进阶版笔记目录链接:
python+opencv进阶版学习笔记目录(适合有一定基础)

基础版形态学:
opencv学习笔记12:图像腐蚀和图像膨胀
opencv学习笔记13:形态学变换(开运算,闭运算,梯度运算)
opencv学习笔记14:图像礼帽,图像黑帽

图像膨胀

使用卷积核对二值图像进行遍历,卷积核对应的图像像素点只要有一个为1,则值为1,否则为0.
即用卷积核对应的最大元素替换掉当前中心像素。

膨胀作用:对象大小增加一个像素,平滑对象边缘,减少或者填充对象之间的距离。

使用方法:dilate
结果=cv2.dilate(二值图像src,卷积核k,迭代次数itreations)
卷积核 正方形数组:如np.ones((5,5),np.uint8)

import cv2 as cv
import numpy as np


def dilate_demo(image):
    print(image.shape)
    gray = cv.cvtColor(image, cv.COLOR_BGR2GRAY)
    ret, binary = cv.threshold(gray, 0, 255,cv.THRESH_BINARY_INV | cv.THRESH_OTSU)
    cv.imshow("binary", binary)
    kernel = cv.getStructuringElement(cv.MORPH_RECT, (5, 5))
    #kernel = np.ones((5, 5), np.uint8)
    dst = cv.dilate(binary, kernel)
    cv.imshow("dilate_demo", dst)
print("--------- Python OpenCV Tutorial ---------")
src = cv.imread("fushi.jpg")
src=cv.resize(src,None,fx=0.4,fy=0.4)
cv.namedWindow("input image", cv.WINDOW_AUTOSIZE)
cv.imshow("input image", src)
dilate_demo(src)
cv.waitKey(0)
cv.destroyAllWindows()
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21

解释说明:
在使用opencv的过程中,我们经常需要各种各样的卷积核。如果是正方形的核还好说,可以使用numpy,但是有时候需要定义椭圆形或者十字形的核,我们就需要用到结构化元素
cv2.getStructuringElement()
第一个参数表示核的形状。可以选择三种
矩形:MORPH_RECT;
交叉形:MORPH_CROSS;
椭圆形:MORPH_ELLIPSE;
第二个参数表示核的尺寸。

注意对象要为白色,本文图对象为黑色,所有我在代码里用啦反二值化

图像腐蚀

腐蚀主要针对的是二值图像,如只有0和1两个值,
两个输入对象:1原始二值图像,2卷积核
使用卷积核遍历原始二值图像,如果卷积核对应的元素值均为1,其值才为1,否则为0。
即用卷积核对应的最小元素替换掉当前中心像素。

腐蚀作用:对象大小减少一个像素,平滑对象边缘,弱化或者分割图像之间的半岛性连接。

使用方法:erode 中文翻译:侵蚀
处理结果=cv2.erode(原始图像src,卷积核kernel,迭代次数iterations)
卷积核kernel:一般为正方形数组
如:k=np.ones((5,5),np.uint8)
迭代次数iterations:腐蚀次数,默认1

import cv2 as cv
import numpy as np


def erode_demo(image):
    print(image.shape)
    gray = cv.cvtColor(image, cv.COLOR_BGR2GRAY)
    ret, binary = cv.threshold(gray, 0, 255, cv.THRESH_BINARY_INV | cv.THRESH_OTSU)
    cv.imshow("binary", binary)
    kernel = cv.getStructuringElement(cv.MORPH_RECT, (3, 3))#卷积核
    #kernel = np.ones((3, 3), np.uint8)
    dst = cv.erode(binary, kernel)
    cv.imshow("erode_demo", dst)
print("--------- Python OpenCV Tutorial ---------")
src = cv.imread("fushi.jpg")
src=cv.resize(src,None,fx=0.4,fy=0.4)
cv.namedWindow("input image", cv.WINDOW_AUTOSIZE)
cv.imshow("input image", src)
erode_demo(src)
cv.waitKey(0)
cv.destroyAllWindows()
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21

对彩色图像进行膨胀或腐蚀

import cv2 as cv
print("--------- Python OpenCV Tutorial ---------")
src = cv.imread("limi.jpg")
src=cv.resize(src,None,fx=0.3,fy=0.3)
cv.namedWindow("input image", cv.WINDOW_AUTOSIZE)
cv.imshow("input image", src)
kernel = cv.getStructuringElement(cv.MORPH_RECT, (3, 3))
dst = cv.erode(src, kernel)#腐蚀
cv.imshow("result", dst)
cv.waitKey(0)
cv.destroyAllWindows()
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

开运算

开运算:对图像先进行腐蚀,然后对腐蚀后的图进行膨胀
开操作=腐蚀+膨胀
主要应用在二值图像,灰度 图像也可以。
可以消除背景噪声
morphologyEx
运算结果=cv2.morphologyEx(源图像img,cv2.MORPH_OPEN,卷积核k)
cv2.MORPH_OPEN:开运算

import cv2 as cv
import numpy as np


def open_demo(image):
    print(image.shape)
    gray = cv.cvtColor(image, cv.COLOR_BGR2GRAY)
    ret, binary = cv.threshold(gray, 0, 255, cv.THRESH_BINARY | cv.THRESH_OTSU)
    cv.imshow("binary", binary)
    kernel = cv.getStructuringElement(cv.MORPH_ELLIPSE, (5, 5))#cv.MORPH_ELLIPSE椭圆形,可以选择其他形状
    binary = cv.morphologyEx(binary, cv.MORPH_OPEN, kernel)
    cv.imshow("open-result", binary)

print("--------- Python OpenCV Tutorial ---------")
src = cv.imread("morph.png")
cv.namedWindow("input image", cv.WINDOW_AUTOSIZE)
cv.imshow("input image", src)
open_demo(src)
cv.waitKey(0)
cv.destroyAllWindows()
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20

消除了背景小白点噪声

闭运算

对图像进行先膨胀,再腐蚀。
有助于关闭前景物体上的小孔,或者小黑点。
morphologyEx
运算结果=cv2.morphologyEx(源图像img,cv2.MORPH_CLOSE,卷积核k)
cv2.MORPH_CLOSE:闭运算
合理选择卷积核大小,太小了无法去除前景图的黑点
主要应用在二值图像,灰度 图像也可以。

import cv2 as cv
import numpy as np

def close_demo(image):
    print(image.shape)
    gray = cv.cvtColor(image, cv.COLOR_BGR2GRAY)
    ret, binary = cv.threshold(gray, 0, 255, cv.THRESH_BINARY | cv.THRESH_OTSU)
    cv.imshow("binary", binary)
    kernel = cv.getStructuringElement(cv.MORPH_RECT, (15, 15))
    binary = cv.morphologyEx(binary, cv.MORPH_CLOSE, kernel)
    cv.imshow("close_demo", binary)
print("--------- Python OpenCV Tutorial ---------")
src = cv.imread("morph1.png")
cv.namedWindow("input image", cv.WINDOW_AUTOSIZE)
cv.imshow("input image", src)
close_demo(src)
cv.waitKey(0)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17

消除了前景色小黑点

顶帽

图像礼帽 也叫图像顶帽
礼帽图像=原始图像-开运算图像
得到噪声图像
开运算:先腐蚀再膨胀
使用方法:morphologyEx
cv2.MORPH_TOPHAT
结果=cv2.morphologyEx(原始图像,cv2.MORPH_TOPHAT,卷积核)
卷积核示例:k=np.ones((10,10),np.uint8)

import cv2 as cv
import numpy as np

def hat_gray_demo(image):
    gray = cv.cvtColor(image, cv.COLOR_BGR2GRAY)
    kernel = cv.getStructuringElement(cv.MORPH_RECT, (15, 15))#卷积核
    dst = cv.morphologyEx(gray, cv.MORPH_TOPHAT, kernel)
    cimage = np.array(gray.shape, np.uint8)
    cimage = 120;
    dst = cv.add(dst, cimage)
    cv.imshow("tophat", dst)
print("--------- Python OpenCV Tutorial ---------")
src = cv.imread("morph.png")
cv.namedWindow("input image", cv.WINDOW_AUTOSIZE)
cv.imshow("input image", src)
hat_gray_demo(src)
cv.waitKey(0)
cv.destroyAllWindows()
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18

代码采用了基于灰度度,也可以基于二值图。
采用不同大小的卷积核,得到的噪声小白点也不一样。

黑帽

黑帽图像=闭运算图像-原始图像
得到图像内部的小孔,或前景色的小黑点
闭运算:对图像进行先膨胀,再腐蚀。有助于关闭前景物体上的小孔,或者小黑点。
使用对象:二值图像
使用方法:morphologyEx
cv2.MORPH_BLACKHAT
结果=cv2.morphologyEx(原始图像,cv2.MORPH_BLACKHAT,卷积核)
卷积核示例:k=np.ones((10,10),np.uint8)

import cv2 as cv
import numpy as np

def hat_binary_demo(image):
    gray = cv.cvtColor(image, cv.COLOR_BGR2GRAY)
    ret, binary = cv.threshold(gray, 0, 255, cv.THRESH_BINARY | cv.THRESH_OTSU)
    kernel = cv.getStructuringElement(cv.MORPH_RECT, (15, 15))
    dst = cv.morphologyEx(binary, cv.MORPH_BLACKHAT, kernel)
    cv.imshow("tophat", dst)
print("--------- Python OpenCV Tutorial ---------")
src = cv.imread("morph1.png")

cv.namedWindow("input image", cv.WINDOW_AUTOSIZE)
cv.imshow("input image", src)
hat_binary_demo(src)
cv.waitKey(0)
cv.destroyAllWindows()
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17

梯度运算

基本梯度运算结果=cv2.morphologyEx(源图像img,cv2.MORPH_GRADIENT,卷积核k)

基本梯度

import cv2 as cv
import numpy as np
def hat_binary_demo(image):
    gray = cv.cvtColor(image, cv.COLOR_BGR2GRAY)
    ret, binary = cv.threshold(gray, 0, 255, cv.THRESH_BINARY | cv.THRESH_OTSU)
    kernel = cv.getStructuringElement(cv.MORPH_RECT, (3, 3))
    dst = cv.morphologyEx(binary, cv.MORPH_GRADIENT, kernel)
    cv.imshow("tophat", dst)
print("--------- Python OpenCV Tutorial ---------")
src = cv.imread("morph1.png")
cv.namedWindow("input image", cv.WINDOW_AUTOSIZE)
cv.imshow("input image", src)
hat_binary_demo(src)
cv.waitKey(0)
cv.destroyAllWindows()
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

外梯度内梯度

import cv2 as cv
import numpy as np

def gradient2_demo(image):
    kernel = cv.getStructuringElement(cv.MORPH_RECT, (3, 3))
    dm = cv.dilate(image, kernel)
    em = cv.erode(image, kernel)
    dst1 = cv.subtract(image, em) # internal gradient
    dst2 = cv.subtract(dm, image) # external gradient
    cv.imshow("internal", dst1)
    cv.imshow("external", dst2)
print("--------- Python OpenCV Tutorial ---------")
src = cv.imread("morph1.png")
cv.namedWindow("input image", cv.WINDOW_AUTOSIZE)
cv.imshow("input image", src)
gradient2_demo(src)
cv.waitKey(0)
cv.destroyAllWindows()
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18

电气专业的计算机萌新,写博文不容易。如果你觉得本文对你有用,请点个赞支持下,谢谢。

文章知识点与官方知识档案匹配,可进一步学习相关知识
OpenCV技能树首页概览20473 人正在系统学习中
注:本文转载自blog.csdn.net的总裁余(余登武)的文章"https://blog.csdn.net/kobeyu652453/article/details/107399855"。版权归原作者所有,此博客不拥有其著作权,亦不承担相应法律责任。如有侵权,请联系我们删除。
复制链接
复制链接
相关推荐
发表评论
登录后才能发表评论和回复 注册

/ 登录

评论记录:

未查询到任何数据!
回复评论:

分类栏目

后端 (14832) 前端 (14280) 移动开发 (3760) 编程语言 (3851) Java (3904) Python (3298) 人工智能 (10119) AIGC (2810) 大数据 (3499) 数据库 (3945) 数据结构与算法 (3757) 音视频 (2669) 云原生 (3145) 云平台 (2965) 前沿技术 (2993) 开源 (2160) 小程序 (2860) 运维 (2533) 服务器 (2698) 操作系统 (2325) 硬件开发 (2492) 嵌入式 (2955) 微软技术 (2769) 软件工程 (2056) 测试 (2865) 网络空间安全 (2948) 网络与通信 (2797) 用户体验设计 (2592) 学习和成长 (2593) 搜索 (2744) 开发工具 (7108) 游戏 (2829) HarmonyOS (2935) 区块链 (2782) 数学 (3112) 3C硬件 (2759) 资讯 (2909) Android (4709) iOS (1850) 代码人生 (3043) 阅读 (2841)

热门文章

101
推荐
关于我们 隐私政策 免责声明 联系我们
Copyright © 2020-2025 蚁人论坛 (iYenn.com) All Rights Reserved.
Scroll to Top