OpenCV-图像处理(10、膨胀与腐蚀)

版权声明:本文由 Micheal 超 博客 创作,转载请附带链接,有问题欢迎交流。 https://blog.csdn.net/qq_42887760/article/details/85928182

形态学操作(morphology operators)-膨胀与腐蚀(Dilation与Erosion)。

  • 图像形态学操作
    • 图像形态学操作 – 基于形状的一系列图像处理操作的合集,主要是基于集合论基础上的形态学数学
    • 形态学有四个基本操作:腐蚀、膨胀、开、闭
    • 膨胀与腐蚀是图像处理中最常用的形态学操作手段
    • 腐蚀和膨胀是对白色部分(高亮部分)而言的,不是黑色部分。膨胀就是图像中的高亮部分进行膨胀,“领域扩张”,效果图拥有比原图更大的高亮区域。腐蚀就是原图中的高亮部分被腐蚀,“领域被蚕食”,效果图拥有比原图更小的高亮区域。
  • 膨胀与腐蚀能实现多种多样的功能,主要如下:
    • 消除噪声
    • 分割(isolate)出独立的图像元素,在图像中连接(join)相邻的元素。
    • 寻找图像中的明显的极大值区域或极小值区域
    • 求出图像的梯度
相关的 API

getStructuringElement(int shape, Size ksize, Point anchor)

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

1. 形态学操作-膨胀

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

2. 形态学操作-腐蚀

  • 相关的API:erode(src, dst, kernel)
    在这里插入图片描述
  • 腐蚀跟膨胀操作的过程类似,唯一不同的是以最小值替换锚点重叠下图像的像素值
  • 形态学操作-腐蚀(感官上图像变粗,变黑了)

在这里插入图片描述

动态调整结构元素大小

  • TrackBar –
    createTrackbar(const String & trackbarname, const String winName, int* value, int count, Trackbarcallback func, void* userdata=0)
    其中最中要的是 callback 函数功能。如果设置为NULL就是说只有值update,但是不会调用callback的函数。

代码示例

#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("E:/Experiment/OpenCV/Pictures/lenanoise.jpg");
	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 );
}

在这里插入图片描述

推荐参考:

  1. https://blog.csdn.net/LYKymy/article/details/83153122
  2. https://blog.csdn.net/huanghuangjin/article/details/80945770

猜你喜欢

转载自blog.csdn.net/qq_42887760/article/details/85928182