08- OpenCV:形态学操作(膨胀与腐蚀 、提取水平与垂直线)

目录

前言

[一、膨胀(Dilation)与 腐蚀(Erosion)](#一、膨胀(Dilation)与 腐蚀(Erosion))

二、形态学操作

1、开操作(Opening)

2、闭操作(Closing)

[3、形态学梯度(Morphological Gradient)](#3、形态学梯度(Morphological Gradient))

[4、顶帽 ( top hat)](#4、顶帽 ( top hat))

[5、黑帽 ( black hat)](#5、黑帽 ( black hat))

6、相关的API

7、代码演示

三、形态学操作应用-提取水平与垂直线

1、原理方法

2、实现步骤


前言

1、了解图像形态学

图像形态学操作是一种基于图像形状的图像处理方法,常用于图像分割、边缘检测、图像增强等领域。

2、图像形态学主要包括腐蚀 (Erosion)、膨胀 (Dilation)、开运算 (Opening)、闭运算(Closing)等操作。

除了以上基本操作,还有其他形态学操作,如击中击不中变换(Hit-or-Miss Transform)、顶帽运算(Top Hat Transform)和黑帽运算(Black Hat Transform)等。

这些图像形态学操作可以通过OpenCV库中的函数进行实现,例如cv::erodecv::dilatecv::morphologyEx等函数。

3、膨胀与腐蚀是图像处理中最常用得形态学手段。

一、膨胀(Dilation)与 腐蚀(Erosion)

1、膨胀含义:

将图像中的前景物体进行扩张,通过在图像上滑动一个结构元素,当结构元素与前景物体有重叠时,将该像素置为1(白色)。膨胀操作可以填充物体内部的空洞,同时使物体边界变得更加清晰。

跟卷积操作类似,假设有图像A和结构元素B,结构元素B在A上面移动,其中B定义其中心为锚点,计算B覆盖下A的最大像素值用来替换锚点的像素,其中B作为结构体可以是任意形状。

2、腐蚀含义:

将图像中的前景物体进行收缩,通过在图像上滑动一个结构元素,当结构元素完全覆盖住前景物体时,将该像素置为0(黑色)。腐蚀操作可以去除小的噪点,同时使物体边界变得模糊。

腐蚀跟膨胀操作的过程类似,唯一不同的是以最小值替换锚点重叠下图像的像素值。

3、相关的API:

(1)getStructuringElement(int shape, Size ksize, Point anchor)

  • 形状 (MORPH_RECT \MORPH_CROSS \MORPH_ELLIPSE)

  • 大小

  • 锚点 默认是Point(-1, -1)意思就是中心像素

(2)dilate(src, dst, kernel)

(3)erode(src, dst, kernel)

4、相关代码演示

cpp 复制代码
#include<opencv2\opencv.hpp>
#include<iostream>

using namespace cv;

Mat src, dst;
char OUTPUT_WIN[] = "output image";
int element_size = 3;
int max_size = 21;
void CallBack_Demo(int, void*);
int main(int argc, char** argv) {

	src = imread("test.jpg");
	if (!src.data) {
		printf("could not load image...\n");
		return -1;
	}
	namedWindow("input image", CV_WINDOW_AUTOSIZE);
	imshow("input image", src);

	namedWindow(OUTPUT_WIN, CV_WINDOW_AUTOSIZE);
	createTrackbar("Element Size :", OUTPUT_WIN, &element_size, max_size, CallBack_Demo);
	CallBack_Demo(0, 0);

	waitKey(0);
	return 0;
}

void CallBack_Demo(int, void*) {
	int s = element_size * 2 + 1;
	Mat structureElement = getStructuringElement(MORPH_RECT, Size(s, s), Point(-1, -1));

	// 膨胀
	// dilate(src, dst, structureElement, Point(-1, -1), 1);

	// 腐蚀
	erode(src, dst, structureElement);

	imshow(OUTPUT_WIN, dst);
	return;
}

效果展示:

二、形态学操作

1、开操作(Opening)

先进行腐蚀操作,再进行膨胀操作。开运算可以消除小的噪点,并保持物体的整体形状不变。

(1)先腐蚀后膨胀

(2)可以去掉小的对象,假设对象是前景色,背景是黑色

2、闭操作(Closing)

先进行膨胀操作,再进行腐蚀操作。闭运算可以填充物体内部的空洞,并保持物体的整体形状不变。

(1)先膨胀后腐蚀(bin2)

(2)可以填充小的洞(fill hole),假设对象是前景色,背景是黑色

3、形态学梯度(Morphological Gradient)

(1)膨胀减去腐蚀

(2)又称为基本梯度(其它还包括-内部梯度、方向梯度)

4、顶帽 ( top hat)

顶帽 是原图像与开操作之间的差值图像

5、黑帽 ( black hat)

黑帽是闭操作图像与源图像的差值图像

6、相关的API

morphologyEx(src, dest, CV_MOP_BLACKHAT, kernel);

// 函数原型:

void morphologyEx (

InputArray src, // 输入图像,可以是单通道灰度图像或多通道彩色图像。

OutputArray dst, // 输出图像,与输入图像具有相同的尺寸和类型。

int op, // 形态学操作类型,可以是以下常量之一:

InputArray kernel, // 结构元素,用于定义形态学操作的形状和大小。可以使用cv::getStructuringElement函数创建不同形状的结构元素。

Point anchor = Point(-1,-1), // 锚点位置,默认为(-1,-1),表示结构元素的中心。

int iterations = 1, // 形态学操作的迭代次数,默认为1。

int borderType = BORDER_CONSTANT, // 边界类型,默认为BORDER_CONSTANT,表示使用常数值进行边界扩展。

const Scalar& borderValue = morphologyDefaultBorderValue() // 边界值,默认为morphologyDefaultBorderValue(),表示使用默认的边界值。

);

其中:

  • op:形态学操作类型,可以是以下常量之一:

    • cv::MORPH_ERODE:腐蚀操作

    • cv::MORPH_DILATE:膨胀操作

    • cv::MORPH_OPEN:开运算

    • cv::MORPH_CLOSE:闭运算

    • cv::MORPH_GRADIENT:形态学梯度

    • cv::MORPH_TOPHAT:顶帽运算

    • cv::MORPH_BLACKHAT:黑帽运算

7、代码演示

三、形态学操作应用-提取水平与垂直线

1、原理方法

图像形态学操作时候,可以通过自定义的结构元素实现结构元素 对输入图像一些对象敏感、另外一些对象不敏感,这样就会让敏 感的对象改变而不敏感的对象保留输出。

通过使用两个最基本的 形态学操作 -- 膨胀与腐蚀,使用不同的结构元素实现对输入图像 的操作、得到想要的结果。

(1)膨胀,输出的像素值是结构元素覆盖下输入图像的最大像素值

二值图像与灰度图像上的膨胀操作:

(2)腐蚀,输出的像素值是结构元素覆盖下输入图像的最小像素值

二值图像与灰度图像上的腐蚀操作

(3)结构元素

1)上述膨胀与腐蚀过程可以使用任意的结构元素

2)常见的形状:矩形、园、直线、磁盘形状、砖石形状等各种自定义形状。

2、实现步骤

(1)输入图像彩色图像 imread

(2)转换为灰度图像 -- cvtColor

(3)转换为二值图像 -- adaptiveThreshold

(4)定义结构元素

(5)开操作 (腐蚀+膨胀)提取 水平与垂直线

(1)输入图像彩色图像 imread

(2)转换为灰度图像 -- cvtColor

(3)转换为二值图像 -- adaptiveThreshold

adaptiveThreshold(

Mat src, // 输入的灰度图像

Mat dest, // 二值图像

double maxValue, // 二值图像最大值

int adaptiveMethod // 自适应方法,只能其中之一 --

// ADAPTIVE_THRESH_MEAN_C ,APTIVE_THRESH_GAUSSIAN_C

int thresholdType,// 阈值类型

int blockSize, // 块大小

double C // 常量C 可以是正数,0,负数

)

(4)定义结构元素

一个像素宽的水平线 - 水平长度 width/30

一个像素宽的垂直线 -- 垂直长度 height/30

(5)开操作 (腐蚀+膨胀)提取 水平与垂直线

后处理

1)bitwise_not(Mat bin, Mat dst)像素取反操作,255 -- SrcPixel

2)模糊(blur)

3、代码演示

cpp 复制代码
#include <opencv2/opencv.hpp>
#include <iostream>

using namespace cv;
int main(int argc, char** argv) {
	Mat src, dst;
	src = imread("D:/vcprojects/images/chars.png");
	if (!src.data) {
		printf("could not load image...\n");
		return -1;
	}

	char INPUT_WIN[] = "input image";
	char OUTPUT_WIN[] = "result image";
	namedWindow(INPUT_WIN, CV_WINDOW_AUTOSIZE);
	imshow(INPUT_WIN, src);

	Mat gray_src;
	cvtColor(src, gray_src, CV_BGR2GRAY);
	imshow("gray image", gray_src);
	
	Mat binImg;
	adaptiveThreshold(~gray_src, binImg, 255, ADAPTIVE_THRESH_MEAN_C, THRESH_BINARY, 15, -2);
	imshow("binary image", binImg);

	// 水平结构元素
	Mat hline = getStructuringElement(MORPH_RECT, Size(src.cols / 16, 1), Point(-1, -1));
	// 垂直结构元素
	Mat vline = getStructuringElement(MORPH_RECT, Size(1, src.rows / 16), Point(-1, -1));
	// 矩形结构
	Mat kernel = getStructuringElement(MORPH_RECT, Size(3, 3), Point(-1, -1));

	Mat temp;
	erode(binImg, temp, kernel);
	dilate(temp, dst, kernel);
	// morphologyEx(binImg, dst, CV_MOP_OPEN, vline);

    // 背景变色
	bitwise_not(dst, dst);

    // 结果更加圆滑些
	//blur(dst, dst, Size(3, 3), Point(-1, -1));
	imshow("Final Result", dst);

	waitKey(0);
	return 0;
}

效果展示:

(1)水平结构元素:

先腐蚀后膨胀,相当于一开始把垂直的元素擦掉,所以就保留了水平的线。

Mat hline = getStructuringElement(MORPH_RECT, Size(src.cols / 16, 1), Point(-1, -1));

erode(binImg, temp, hline)

dilate(temp, dst, hline);

等同于:

morphologyEx(binImg, dst, CV_MOP_OPEN, hline);

(2)垂直结构元素

先腐蚀后膨胀,相当于一开始把水平的元素擦掉,所以就保留了垂直的线。

Mat vline = getStructuringElement(MORPH_RECT, Size(1, src.rows / 16), Point(-1, -1));

morphologyEx(binImg, dst, CV_MOP_OPEN, vline);

(3)矩形结构

矩形大小的干扰项都去掉。

Mat kernel = getStructuringElement(MORPH_RECT, Size(4, 4), Point(-1, -1));

morphologyEx(binImg, dst, CV_MOP_OPEN, kernel);

相关推荐
STRUGGLE_xlf几秒前
产品经理的 Claude Code 免费教程——模块 3:Nano Banana(AI 图像生成)
人工智能·产品经理
却道天凉_好个秋几秒前
pytorch(一):张量
人工智能·pytorch·python·深度学习
搞科研的小刘选手3 分钟前
【高届数人文社科会议】第十二届人文学科和社会科学研究国际学术会议(ICHSSR 2026)
大数据·人工智能·电子信息·电子工程·学术会议·信息工程·电路工程
0xDevNull4 分钟前
现代AI系统架构全景解析
人工智能·系统架构
华清远见IT开放实验室6 分钟前
AI 算法核心知识清单(深度实战版1)
人工智能·python·深度学习·学习·算法·机器学习·ai
亚远景aspice7 分钟前
亚远景推出国内首款汽车研发合规AI全栈产品 填补和引领行业AI应用
大数据·人工智能
大囚长9 分钟前
大模型知识与逻辑推理能力的关系
人工智能
世优科技虚拟人10 分钟前
重庆合川发布陶行知AI数字人,世优科技提供数字人全栈技术支持
人工智能·科技·数字人·智能交互
云烟成雨TD14 分钟前
Spring AI 1.x 系列【27】Chat Memory API:让 LLM 拥有上下文记忆能力
java·人工智能·spring
kimi-22215 分钟前
如何让大语言模型稳定输出 JSON 的三层防御体系
人工智能·语言模型·json