基于 OpenCV 的图像形态学与边缘检测

文章目录


一、图像形态学基本操作

图像形态学是图像处理的重要分支,主要用于分析和处理图像中的形状特征。下面将详细介绍几种核心的形态学操作。

1. 图像腐蚀

图像腐蚀操作能够消除图像中较小的物体或细节,使图像整体"收缩"。其核心函数为:

python 复制代码
cv2.erode(src, kernel, dst, anchor, iterations, borderType, borderValue)

参数解析:

  • src:输入图像
  • kernel:腐蚀操作的结构元素,其形状和大小直接影响腐蚀效果
  • iterations:迭代次数,次数越多腐蚀效果越明显

示例代码:

python 复制代码
import numpy as np
import cv2

sun = cv2.imread('sun.png')
cv2.imshow('src', sun)
cv2.waitKey(0)

kernel = np.ones((3, 3), np.uint8)  # 3x3的腐蚀核
erosion_1 = cv2.erode(sun, kernel, iterations=2)  # 迭代2次
cv2.imshow('erosion_1', erosion_1)
cv2.waitKey(0)

2. 图像膨胀

图像膨胀是腐蚀的逆操作,能够扩大图像中的前景区域,填补空洞和裂缝。

python 复制代码
cv2.dilate(img, kernel, iterations)

参数解析:

  • img:目标图片
  • kernel:膨胀操作的内核,默认为3x3矩阵
  • iterations:膨胀次数

示例代码:

python 复制代码
text = cv2.imread('text.png')
cv2.imshow('src1', text)
cv2.waitKey(0)

kernel = np.ones((2, 2), np.uint8)  # 2x2的膨胀核
text_new = cv2.dilate(text, kernel, iterations=2)
cv2.imshow('text_new', text_new)
cv2.waitKey(0)

3. 开运算与闭运算

开运算是先腐蚀后膨胀的操作组合:

python 复制代码
cv2.morphologyEx(src, cv2.MORPH_OPEN, kernel)

作用: 平滑物体轮廓、断开狭窄的连接、清除细小突起物。

python 复制代码
Fingerprint1 = cv2.imread('Fingerprint1.png')
cv2.imshow('src2', Fingerprint1)
cv2.waitKey(0)

kernel = np.ones((2, 2), np.uint8)
Fingerprint1_new = cv2.morphologyEx(Fingerprint1, cv2.MORPH_OPEN, kernel)
cv2.imshow('Fingerprint1_new', Fingerprint1_new)
cv2.waitKey(0)

闭运算是先膨胀后腐蚀的操作组合:

python 复制代码
cv2.morphologyEx(src, cv2.MORPH_CLOSE, kernel)

作用: 填补细小空洞、连接断裂轮廓、弥合狭窄间隙。

python 复制代码
Fingerprint2 = cv2.imread('Fingerprint2.png')
cv2.imshow('src3', Fingerprint2)
cv2.waitKey(0)

kernel = np.ones((4, 4), np.uint8)
Fingerprint2_new = cv2.morphologyEx(Fingerprint2, cv2.MORPH_CLOSE, kernel)
cv2.imshow('Fingerprint2_new', Fingerprint2_new)
cv2.waitKey(0)

4. 梯度运算

梯度运算通过膨胀与腐蚀的差值来突出显示图像中强度变化剧烈的区域(边缘)。

python 复制代码
# 膨胀操作
pz_text = cv2.dilate(text, kernel, iterations=1)
cv2.imshow('pz_text', pz_text)
cv2.waitKey(0)

# 腐蚀操作
fs_text = cv2.erode(text, kernel, iterations=1)
cv2.imshow('fs_text', fs_text)
cv2.waitKey(0)

# 梯度运算(膨胀-腐蚀)
bianyuan = cv2.morphologyEx(text, cv2.MORPH_GRADIENT, kernel)
cv2.imshow('bianyuan', bianyuan)
cv2.waitKey(0)

5. 顶帽与黑帽变换

顶帽变换:原始图像与开运算结果的差值,用于提取比周围区域亮的细节。

python 复制代码
tophat = cv2.morphologyEx(sun, cv2.MORPH_TOPHAT, kernel)

黑帽变换:闭运算结果与原始图像的差值,用于提取比周围区域暗的细节。

python 复制代码
blackhat = cv2.morphologyEx(sun, cv2.MORPH_BLACKHAT, kernel)

完整示例:

python 复制代码
sun = cv2.imread('sun.png')
cv2.imshow('sun_yuantu', sun)
cv2.waitKey(0)

kernel = np.ones((2, 2), np.uint8)

# 开运算
open_sun = cv2.morphologyEx(sun, cv2.MORPH_OPEN, kernel)
cv2.imshow('open_sun', open_sun)
cv2.waitKey(0)

# 顶帽
tophat = cv2.morphologyEx(sun, cv2.MORPH_TOPHAT, kernel)
cv2.imshow('TOPHAT', tophat)
cv2.waitKey(0)

# 闭运算
close_sun = cv2.morphologyEx(sun, cv2.MORPH_CLOSE, kernel)
cv2.imshow('close_sun', close_sun)
cv2.waitKey(0)

# 黑帽
blackhat = cv2.morphologyEx(sun, cv2.MORPH_BLACKHAT, kernel)
cv2.imshow('BLACKHAT', blackhat)
cv2.waitKey(0)

cv2.destroyAllWindows()

二、Sobel边缘检测算子

Sobel算子是一种基于一阶导数的边缘检测方法,能够有效检测图像中的水平和垂直边缘。

Sobel函数原型

python 复制代码
cv2.Sobel(src, ddepth, dx, dy[, ksize[, scale[, delta[, borderType]]]])

关键参数解析:

  • src:输入图像
  • ddepth:输出图像深度,-1表示与原图相同,cv2.CV_64F可保留负数值
  • dx, dy:x和y方向的导数阶数
  • ksize:Sobel核大小,通常为1,3,5或7

边缘检测实现

python 复制代码
import cv2
import numpy as np

yuan = cv2.imread('yuan.png')
cv2.imshow('yuan', yuan)
cv2.waitKey(0)

# x方向边缘检测(仅正梯度)
yuan_x = cv2.Sobel(yuan, -1, dx=1, dy=0)
cv2.imshow('yuan_x', yuan_x)
cv2.waitKey(0)

# x方向完整边缘(保留负梯度信息)
yuan_x_64 = cv2.Sobel(yuan, cv2.CV_64F, dx=1, dy=0)  # 使用float64保存负数
yuan_x_full = cv2.convertScaleAbs(yuan_x_64)  # 取绝对值转换
cv2.imshow('yuan_x_full', yuan_x_full)
cv2.waitKey(0)

# y方向完整边缘检测
yuan_y_64 = cv2.Sobel(yuan, cv2.CV_64F, dx=0, dy=1)
yuan_y_full = cv2.convertScaleAbs(yuan_y_64)
cv2.imshow('yuan_y_full', yuan_y_full)
cv2.waitKey(0)

# 同时检测x和y方向(不推荐)
yuan_xy = cv2.Sobel(yuan, -1, dx=1, dy=1)
cv2.imshow('yuan_xy', yuan_xy)
cv2.waitKey(0)

# 加权融合x和y方向边缘(推荐方法)
yuan_xy_full = cv2.addWeighted(yuan_x_full, 1, yuan_y_full, 1, 0)
cv2.imshow('yuan_xy_full', yuan_xy_full)
cv2.waitKey(0)

cv2.destroyAllWindows()

三、图像边界填充技术

边界填充是图像处理中的基础操作,用于处理卷积操作时的边界问题。

python 复制代码
import cv2

ys = cv2.imread(r'picture_1.jpg')
ys = cv2.resize(ys, dsize=None, fx=0.2, fy=0.2)  # 图像缩放

top, bottom, left, right = 50, 50, 50, 50

# 五种边界填充方式
constant = cv2.copyMakeBorder(ys, top, bottom, left, right, 
                              borderType=cv2.BORDER_CONSTANT, 
                              value=(229, 25, 80))  # 常数填充

reflect = cv2.copyMakeBorder(ys, top, bottom, left, right, 
                             borderType=cv2.BORDER_REFLECT)  # 镜像反射

reflect101 = cv2.copyMakeBorder(ys, top, bottom, left, right, 
                                borderType=cv2.BORDER_REFLECT101)  # 镜像反射101

replicate = cv2.copyMakeBorder(ys, top, bottom, left, right, 
                               borderType=cv2.BORDER_REPLICATE)  # 复制边缘像素

wrap = cv2.copyMakeBorder(ys, top, bottom, left, right, 
                          borderType=cv2.BORDER_WRAP)  # 环绕填充

# 显示各种填充效果
cv2.imshow('yuantu', ys)
cv2.waitKey(0)
cv2.imshow('CONSTANT', constant)
cv2.waitKey(0)
cv2.imshow('REFLECT', reflect)
cv2.waitKey(0)
cv2.imshow('REFLECT_101', reflect101)
cv2.waitKey(0)
cv2.imshow('REPLICATE', replicate)
cv2.waitKey(0)
cv2.imshow('WRAP', wrap)
cv2.waitKey(0)
cv2.destroyAllWindows()

边界填充类型说明:

  • BORDER_CONSTANT:使用指定颜色值填充
  • BORDER_REFLECT:边界像素的镜像反射
  • BORDER_REFLECT101:改进的镜像反射,边界像素只出现一次
  • BORDER_REPLICATE:复制最边缘的像素值
  • BORDER_WRAP:像素值环绕填充
相关推荐
saoys11 小时前
Opencv 学习笔记:创建与原图等尺寸的空白图像
笔记·opencv·学习
少林码僧17 小时前
2.31 机器学习神器项目实战:如何在真实项目中应用XGBoost等算法
人工智能·python·算法·机器学习·ai·数据挖掘
智航GIS17 小时前
10.4 Selenium:Web 自动化测试框架
前端·python·selenium·测试工具
jarreyer17 小时前
摄像头相关记录
python
宝贝儿好17 小时前
【强化学习】第六章:无模型控制:在轨MC控制、在轨时序差分学习(Sarsa)、离轨学习(Q-learning)
人工智能·python·深度学习·学习·机器学习·机器人
大、男人17 小时前
python之asynccontextmanager学习
开发语言·python·学习
智驱力人工智能18 小时前
守护流动的规则 基于视觉分析的穿越导流线区检测技术工程实践 交通路口导流区穿越实时预警技术 智慧交通部署指南
人工智能·opencv·安全·目标检测·计算机视觉·cnn·边缘计算
默默前行的虫虫18 小时前
nicegui文件上传归纳
python
一个没有本领的人19 小时前
UIU-Net运行记录
python