目录
概述:
运算类型 | 操作 | 目的 |
开运算 | 先腐蚀再膨胀 | 可在纤细点出分离物体。有助于消除噪音 |
闭运算 | 先膨胀后腐蚀 | 用于排除前景对象中的小孔或对象上的小黑点 |
形态学梯度 | 膨胀图与腐蚀图之差 | 用于保留目标物体的边缘轮廓 |
顶帽 | 原图与开运算图之差 | 分离比邻近点亮的斑块,用于突出原图像中比周围亮的区域 |
黑帽 | 闭运算图-原图像 | 分离比邻近点暗的斑块,突出原图像中比周围暗的区域 |
形态学处理往往是在阈值处理之后才进行的,因为当图像被转化为二值图以后,这个时候只有黑白两者颜色,然后再进行形态学处理是效果最好的。
morphologyEX()函数
morphologyEx(Mat src, Mat dst, int op, Mat kernel, Point anchor, int iterations, int borderType, Scalar borderValue)
参数介绍:
第一个参数,InputArray类型的src,输入图像,即源图像,填Mat类的对象即可。图像位深应该为以下五种之一:CV_8U, CV_16U,CV_16S, CV_32F 或CV_64F。
第二个参数,OutputArray类型的dst,即目标图像,函数的输出参数,需要和源图片有一样的尺寸和类型。
第三个参数,int类型的op,表示形态学运算的类型,可以是如下之一的标识符:enum MorphTypes{ MORPH_ERODE = 0, //腐蚀 MORPH_DILATE = 1, //膨胀 MORPH_OPEN = 2, //开操作 MORPH_CLOSE = 3, //闭操作 MORPH_GRADIENT = 4, //梯度操作 MORPH_TOPHAT = 5, //顶帽操作 MORPH_BLACKHAT = 6, //黑帽操作 MORPH_HITMISS = 7 };
第四个参数,InputArray类型的kernel,形态学运算的内核。
一、开运算(分开)
1、基础理论
1、作用:
1、分离物体,消除小区域。
2、消除噪点,消除小干扰块,而不影响原来的图像。
2、过程:
先腐蚀运算,再膨胀运算(看上去把细微连在一起的两块目标分开了)
(1)腐蚀
(2)膨胀
2、代码
C++:
//开运算
void Open()
{
Mat kernel = getStructuringElement(MORPH_RECT, Size(11, 11)); //创建结构元
// 矩形卷积核 尺寸为(19, 19)宽高
morphologyEx(img, dst, MORPH_OPEN, kernel, Point(-1, -1)); // 形态学处理--开运算
// 原图 新图 开运算 卷积核 锚点
imshow("新图", dst); // 显示形态学处理后的效果
}
python:
# 开运算(先腐后膨)
def Open():
open = cv2.morphologyEx(img, cv2.MORPH_OPEN, (7, 7), iterations=5)
# 类型 卷积核大小 迭代次数
cv2.imshow('open', open)
3、效果
二、闭运算(封闭)
1、基础理论
1、作用
消除闭合区域内的空洞,填充闭合区域。
2、过程
先膨胀运算,再腐蚀运算(看上去将两个细微连接的图块封闭在一起)
(1)膨胀
(2)腐蚀
2、代码
C++:
//闭运算
void Close()
{
Mat kernel = getStructuringElement(MORPH_RECT, Size(19, 19)); //创建结构元
// 矩形卷积核 尺寸为(19, 19)宽高
morphologyEx(img, dst, MORPH_CLOSE, kernel, Point(-1, -1)); // 形态学处理--开运算
// 原图 新图 闭运算 卷积核 锚点
imshow("闭运算", dst); // 显示形态学处理后的效果
}
python:
# 闭运算(先膨后腐)
def Close():
close = cv2.morphologyEx(img, cv2.MORPH_CLOSE, (7, 7), iterations=5)
# 类型 卷积核大小 迭代次数
cv2.imshow('close', close)
3、效果
总代码
C++:
//开运算与闭运算(形态学)
#include <iostream>
#include <opencv2/opencv.hpp>
using namespace cv;
using namespace std;
Mat img, dst;
//图像初始化
void Image_Init()
{
img = imread("Resource/test5.jpg");
dst = Mat::zeros(img.size(), img.type());
if (img.empty())
{
printf("图像加载失败");
exit(0);
}
}
//开运算
void Open()
{
Mat kernel = getStructuringElement(MORPH_RECT, Size(19, 19)); //创建结构元
// 矩形卷积核 尺寸为(11,11)宽高
morphologyEx(img, dst, MORPH_OPEN, kernel, Point(-1, -1)); // 形态学处理--开运算
// 原图 新图 开运算 卷积核 锚点
imshow("开运算", dst); // 显示形态学处理后的效果
}
//闭运算
void Close()
{
Mat kernel = getStructuringElement(MORPH_RECT, Size(19, 19)); //创建结构元
// 矩形卷积核 尺寸为(11,11)宽高
morphologyEx(img, dst, MORPH_CLOSE, kernel, Point(-1, -1)); // 形态学处理--开运算
// 原图 新图 闭运算 卷积核 锚点
imshow("闭运算", dst); // 显示形态学处理后的效果
}
//显示图像
void Show()
{
imshow("原图", img);
}
int main()
{
Image_Init(); //图像初始化
Open(); //开运算
Close(); //闭运算
Show(); //显示原图像
waitKey(0);
return 0;
}
python:
# 形态学(膨胀、腐蚀、开闭运算、顶帽与底帽)
import cv2
# 膨胀
def Dilate():
# 膨胀
dilate = cv2.dilate(img, kernel=(7, 7), iterations=1)
# 卷积核大小 迭代次数
cv2.imshow("dilate", dilate)
# 腐蚀
def Enrode():
# 腐蚀
erode = cv2.erode(img, kernel=(7, 7), iterations=5)
# 卷积核大小 迭代次数
cv2.imshow("erode", erode)
# 开运算(先腐后膨)
def Open():
open = cv2.morphologyEx(img, cv2.MORPH_OPEN, (7, 7), iterations=5)
# 类型 卷积核大小 迭代次数
cv2.imshow('open', open)
# 闭运算(先膨后腐)
def Close():
close = cv2.morphologyEx(img, cv2.MORPH_CLOSE, (7, 7), iterations=5)
# 类型 卷积核大小 迭代次数
cv2.imshow('close', close)
# 顶帽(原-开)
def TopHat():
tophat = cv2.morphologyEx(img, cv2.MORPH_TOPHAT, (7, 7), iterations=5)
# 类型 卷积核 迭代次数
cv2.imshow('TopHat', tophat)
# 底帽(原-闭)
def BlackHat():
blackhat = cv2.morphologyEx(img, cv2.MORPH_BLACKHAT, (7, 7), iterations=5)
# 类型 卷积核 迭代次数
cv2.imshow('BlackHat', blackhat)
if __name__ == '__main__':
# 读取图片
img = cv2.imread("Resource/test5.jpg")
cv2.imshow("img", img)
Dilate() #膨胀
Enrode() #腐蚀
Open() #开运算
Close() #闭运算
TopHat() #顶帽运算
BlackHat() #底帽运算
cv2.waitKey(0)
参考资料:
https://blog.csdn.net/weixin_41695564/article/details/79935028