10 OpenCV形态学操作之膨胀与腐蚀

痞子三分冷 提交于 2020-02-04 03:42:39

一、形态学操作

  • 图像形态学操作 – 基于形状的一系列图像处理操作的合集,主要是基于集合论基础上的形态学数学
  • 形态学有四个基本操作:腐蚀、膨胀、开、闭
  • 膨胀与腐蚀是图像处理中最常用的形态学操作手段,主要功能有:
    • 消除噪声
    • 分割(isolate)出独立的图像元素,在图像中连接(join)相邻的元素
    • 寻找图像中的明显的极大值区域或极小值区域
    • 求出图像的梯度

二、膨胀

  • 跟卷积操作类似,假设有图像A和结构元素B,结构元素B在A上面移动,其中B定义其中心为锚点,计算B覆盖下A的最大像素值用来替换锚点的像素,其中B作为结构体可以是任意形状
    在这里插入图片描述
  • dilate(src,dst,kernel);
    在这里插入图片描述

三、腐蚀

  • 腐蚀跟膨胀操作的过程类似,唯一不同的是以最小值替换锚点重叠下图像的像素值
    在这里插入图片描述
  • erode(src,dst,kernel);
    在这里插入图片描述

四、相关API

  • getStructuringElement(int shape, Size ksize, Point anchor)
    • 形状 (MORPH_RECT \MORPH_CROSS \MORPH_ELLIPSE)
    • 大小
    • 锚点 默认是Point(-1, -1)意思就是中心像素

五、示例

#include<opencv2/opencv.hpp>
#include<iostream>
#include<math.h>
using namespace cv;
using namespace std;

Mat src, erode_dst, dilate_dst;
char input_Win[] = "input windows", dilate_Win[] = "Dilation windows", Erode_Win[] = "Erosion windows";
int dilate_elem = 0, erode_elem = 0;
int dilate_size = 0, erode_size = 0;
int const max_elem = 2;
int const max_kernel_size = 21;

void Dilation(int, void*);//膨胀
void Erosion(int, void*);//腐蚀

int main(int argc, char** argv) {
	//1、加载图像,可以是BGR或灰度
	src = imread("images/10.png");
	if (src.empty()) {
		printf("Could not load Image ...");
		return -1;
	}

	namedWindow(input_Win, CV_WINDOW_AUTOSIZE);
	imshow(input_Win, src);

	//2、创建两个窗口(一个用于膨胀Dilation,另一个用于侵蚀Erosion)
	//每次移动任何滑块时,都会调用用户的Erosion或Dilation函数,它将根据当前的trackbar值更新输出图像。
	namedWindow(dilate_Win, CV_WINDOW_AUTOSIZE);
	namedWindow(Erode_Win, CV_WINDOW_AUTOSIZE);

	//3、为每个操作创建两组轨道栏:

	//3.1、第一个轨道栏“Element”返回erosion_elem或dilation_elem
	createTrackbar("卷积核类型", dilate_Win, &dilate_elem, max_elem, Dilation);
	//3.2、第二个轨道栏“内核大小”返回相应操作的erosion_size或dilation_size。
	createTrackbar("卷积核大小", dilate_Win, &dilate_size, max_kernel_size, Dilation);


	createTrackbar("卷积核类型", Erode_Win, &erode_elem, max_elem, Erosion);
	createTrackbar("卷积核大小", Erode_Win, &erode_size, max_kernel_size, Erosion);

	Dilation(0, 0);
	Erosion(0, 0);

	waitKey(0);
}

//膨胀
void Dilation(int, void*) {
	int dilate_type;//内核选择三种形状中的任何一种
	if (dilate_elem == 0) { dilate_type = MORPH_RECT; }//矩形内核:MORPH_RECT
	else if (dilate_elem == 1) { dilate_type = MORPH_CROSS; }//十字架内核:MORPH_CROSS
	else if (dilate_elem == 2) { dilate_type = MORPH_ELLIPSE; }//椭圆内核:MORPH_ELLIPSE

	Mat kernel = getStructuringElement(dilate_type, Size(2 * dilate_size + 1, 2 * dilate_size + 1), Point(dilate_size, dilate_size));
	dilate(src, dilate_dst, kernel);
	imshow(dilate_Win, dilate_dst);
}

//腐蚀
void Erosion(int, void*) {
	int erosion_type;//内核选择三种形状中的任何一种
	if (erode_elem == 0) { erosion_type = MORPH_RECT; }//矩形内核:MORPH_RECT
	else if (erode_elem == 1) { erosion_type = MORPH_CROSS; }//十字架内核:MORPH_CROSS
	else if (erode_elem == 2) { erosion_type = MORPH_ELLIPSE; }//椭圆内核:MORPH_ELLIPSE

	Mat kernel = getStructuringElement(erosion_type, Size(2 * erode_size + 1, 2 * erode_size + 1), Point(erode_size, erode_size));
	erode(src, erode_dst, kernel);
	imshow(Erode_Win, erode_dst);
}

在这里插入图片描述

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!