Opencv学习笔记(2)——模糊处理与形态学基本操作

Opencv学习笔记(2)——模糊处理与形态学基本操作

在本节我将为大家介绍Opencv的模糊处理与形态学基本操作

一.模糊图像

1.模糊原理

1.Smooth/Blur 是图像处理中最简单和常用的操作之一。
2.使用该操作的原因之一就为了给图像预处理时候减低噪声。
3.使用Smooth/Blur操作其背后是数学的卷积计算。
Opencv学习笔记(2)——模糊处理与形态学基本操作_第1张图片
注:h(k,l)称为卷积核或卷积算子。

图像演示:
Opencv学习笔记(2)——模糊处理与形态学基本操作_第2张图片
假设有6x6的图像像素点矩阵。

卷积过程:6x6上面是个3x3的窗口,从左向右,从上向下移动,黄色的每个像个像素点值之和取平均值赋给中心红色像素作为它卷积处理之后新的像素值。每次移动一个像素格。

2.常见模糊方法

1.归一化盒子滤波(均值滤波)
Opencv学习笔记(2)——模糊处理与形态学基本操作_第3张图片
将结构元素内的各像素点的均值赋予锚点,从而达到降低对比度,达到滤波降噪目的,卷积算子均为1。

2.高斯滤波
在这里插入图片描述
卷积算子取值依据正态分布函数取得。

3.中值滤波
Opencv学习笔记(2)——模糊处理与形态学基本操作_第4张图片特点:
统计排序滤波器。
中值对椒盐噪声有很好的抑制作用。
注:中值滤波将结构元素中像素点的中值像素赋予给锚点。
椒盐噪声:形象比喻,好比一锅白粥里面洒了一些胡椒和盐粒,使得整个图像有那种极大或极小的噪声点。

4.高斯双边滤波
均值模糊无法克服边缘像素信息丢失缺陷。原因是均值滤波是基于平均权重。
高斯模糊部分克服了该缺陷,但是无法完全避免,因为没有考虑像素值的不同。
高斯双边模糊 – 是边缘保留的滤波方法,避免了边缘信息丢失,保留了图像轮廓不变。
Opencv学习笔记(2)——模糊处理与形态学基本操作_第5张图片
高斯双边模糊考虑的结构元素像素点之间的差异,若像素点差异过大,超过规定阈值,则不做模糊操作即添加值域核。若像素点差异未超过规定阈值,则进行模糊操作,考虑空间差异,即添加空域核。空域核和值域核共同组成了高斯双边模糊的卷积核。

3.相关API函数

1.均值模糊

- blur(Mat src, Mat dst, Size(xradius, yradius), Point(-1,-1));
参数说明:
src:源图像
dst:目标图像
Size(xradius, yradius):结构元素尺寸,为奇数
Point(-1,-1):锚点位置,一般用(-1-1),表示结构元素中心位置

在这里插入图片描述

2.高斯模糊

-GaussianBlur(Mat src, Mat dst, Size(11, 11), sigmax, sigmay);
参数说明:
src:源图像
dst:目标图像
Size(xradius, yradius):结构元素尺寸,为奇数
sigmax, sigmay:影响正态分布函数的取值从而影响卷积算子的取值,可都不输入,则根据size确定取值
其中Size(x, y), x, y 必须是正数而且是奇数

3.中值模糊

medianBlur(Mat src, Mat dest, ksize);
参数说明:
src:源图像
dst:目标图像
ksize:结构元素尺寸,为奇数
中值模糊的ksize大小必须是大于1而且必须是奇数。

4.高斯双边滤波

bilateralFilter(src, dest, d=15, 150, 3);
参数说明:
 - 15 –计算的半径,半径之内的像数都会被纳入计算,如果提供-1 则根据sigma space参数取值
 - 150 – sigma color 决定多少差值之内的像素会被计算
 - 3 – sigma space 如果d的值大于0则声明无效,否则根据它来计算d值

4.程序运行

1.均值模糊与高斯模糊

#include  
#include  
using namespace cv;

int main(int argc, char** argv) {
	Mat src, dst;
	src = imread("D:/photos/2.jpg");
	if (!src.data) {
		printf("could not load image...\n");
		return -1;
	}
	char input_title[] = "input image";
	char output_title[] = "blur image";
	namedWindow(input_title, CV_WINDOW_AUTOSIZE);
	namedWindow(output_title, CV_WINDOW_AUTOSIZE);
	imshow(input_title, src);

	blur(src, dst, Size(11, 11), Point(-1, -1));//均值模糊
	imshow(output_title, dst);

	Mat gblur;
	GaussianBlur(src, gblur, Size(11, 11), 11, 11);//高斯模糊,sigmax,sigay均取11
	imshow("gaussian blur", gblur);

	waitKey(0);
	return 0;
}

运行效果:

2.中值模糊

#include  
#include  
using namespace cv;

int main(int argc, char** argv) {
	Mat src, dst;
	src = imread("D:/photos/21.jpg");
	if (!src.data) {
		printf("could not load image...\n");
		return -1;
	}
	namedWindow("input image", CV_WINDOW_AUTOSIZE);
	imshow("input image", src);

	medianBlur(src, dst, 3);//中值模糊
	imshow("medianBlur image", dst);//去椒盐噪声效果较好
	waitKey(0);
	return 0;

}

运行效果:
Opencv学习笔记(2)——模糊处理与形态学基本操作_第6张图片
3.高斯双边模糊

#include  
#include  
using namespace cv;

int main(int argc, char** argv) {
	Mat src, dst;
	src = imread("D:/photos/21.jpg");
	if (!src.data) {
		printf("could not load image...\n");
		return -1;
	}
	namedWindow("input image", CV_WINDOW_AUTOSIZE);
	imshow("input image", src);
	bilateralFilter(src, dst, 15, 100, 5);//双边模糊
	namedWindow("BiBlur Filter Result", CV_WINDOW_AUTOSIZE);
	imshow("BiBlur Filter Result", dst);//双边模糊

	Mat resultImg;
	Mat kernel = (Mat_<int>(3, 3) << 0, -1, 0, -1, 5, -1, 0, -1, 0);//掩膜算子,提高对比度
	filter2D(dst, resultImg, -1, kernel, Point(-1, -1), 0);
	imshow("Final Result", resultImg);//双边模糊后再提高其图像对比度
	
	waitKey(0);
	return 0;

}

运行效果:

二.形态学操作

1.形态学操作原理

1.形态学操作(morphology operators)-膨胀

  • 图像形态学操作 – 基于形状的一系列图像处理操作的合集,主要是基于集合论基础上的形态学数学。
  • 形态学有四个基本操作:腐蚀、膨胀、开、闭
  • 膨胀与腐蚀是图像处理中最常用的形态学操作手段。

形态学操作-膨胀
跟卷积操作类似,假设有图像A和结构元素B,结构元素B在A上面移动,其中B定义其中心为锚点,计算B覆盖下A的最大像素值用来替换锚点的像素,其中B作为结构体可以是任意形状。
Opencv学习笔记(2)——模糊处理与形态学基本操作_第7张图片注:以结构元素中各像素点的最大值来替代锚点中的值

2.形态学操作-腐蚀
腐蚀跟膨胀操作的过程类似,唯一不同的是以最小值替换锚点重叠下图像的像素值。
Opencv学习笔记(2)——模糊处理与形态学基本操作_第8张图片
注:以结构元素中的最小值替代锚点重叠下图像的像素值。

3.开操作- open

  • 先腐蚀后膨胀
    在这里插入图片描述
  • 可以去掉小的对象,假设对象是前景色,背景是黑色
    Opencv学习笔记(2)——模糊处理与形态学基本操作_第9张图片
    4.闭操作-close
  • 先膨胀后腐蚀(bin2)
    在这里插入图片描述
  • 可以填充小的洞(fill hole),假设对象是前景色,背景是黑色
    Opencv学习笔记(2)——模糊处理与形态学基本操作_第10张图片
    5.形态学梯度- Morphological Gradient
  • 膨胀减去腐蚀
    在这里插入图片描述
  • 又称为基本梯度(其它还包括-内部梯度、方向梯度)
    Opencv学习笔记(2)——模糊处理与形态学基本操作_第11张图片
    6.顶帽 – top hat
  • 顶帽 是原图像与开操作之间的差值图像
    Opencv学习笔记(2)——模糊处理与形态学基本操作_第12张图片
    7.黑帽-black hat
  • 黑帽是闭操作图像与源图像的差值图像
    Opencv学习笔记(2)——模糊处理与形态学基本操作_第13张图片

2.相关API

1.创建结构元素

getStructuringElement(int shape, Size ksize, Point anchor)//创建结构元素
参数说明:
shape:结构元素形状,可选参数:MORPH_RECT(矩形)\MORPH_CROSS(十字架型) \MORPH_ELLIPSE(椭圆)
ksize:结构元素形状
anchor:锚点位置,默认是Point(-1, -1)意思就是中心像素

2.动态调整结构元素大小——TrackBar功能

createTrackbar(const String & trackbarname, const String winName,  int* value, int count, Trackbarcallback func, void* userdata=0);
参数说明:
trackbarname:工具条名称
winName:所需要用到的图像窗口明辰
value:需要动态改变的变量指针
count:需要动态变化的变量的最大值
func:拉动滑条时,所想要调用的函数名

3.膨胀函数API——dilate

 dilate(src, dst, kernel) ;
参数说明:
src:源图像
dst:目标图像
kernel:函数所需结构元素

在这里插入图片描述
4.腐蚀函数API——erode

erode(src, dst, kernel);
参数说明:
src:源图像
dst:目标图像
kernel:函数所需结构元素

在这里插入图片描述
5.其他形态学操作——morphologyEx

morphologyEx(src, dest, int OPT , kernel);
参数说明:
- Mat src – 输入图像
- Mat dest – 输出结果
- int OPT – CV_MOP_OPEN(开操作)/ CV_MOP_CLOSE(闭操作)/ CV_MOP_GRADIENT(梯度操作) / CV_MOP_TOPHAT(顶帽)/ CV_MOP_BLACKHAT(黑帽) 形态学操作类型
- kernel:函数所需结构元素
- int Iteration 迭代次数,默认是1
eg:morphologyEx(src, dest, CV_MOP_BLACKHAT, kernel)

3.程序运行

1.腐蚀与膨胀

#include  
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("D:/photos/21.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;
}

运行结果:
Opencv学习笔记(2)——模糊处理与形态学基本操作_第14张图片
2.顶帽操作

#include
#include
using namespace cv;

int main(int argc, char** argv) {
	Mat src, dst;
	src = imread("D:/photos/21.jpg");
	if (!src.data) {
		std::cout << "could not find image...\n";
		return -1;
	}
	namedWindow("input_image", CV_WINDOW_AUTOSIZE);
	imshow("input_image", src);
	char output_title[] = "morphology demo";
	namedWindow(output_title, CV_WINDOW_AUTOSIZE);
	
	Mat kernel = getStructuringElement(MORPH_RECT, Size(3, 3), Point(-1, -1));//定义结构元素
	morphologyEx(src, dst, CV_MOP_TOPHAT, kernel);//顶帽操作,原图像与开操作(先腐蚀后膨胀)的差值
	imshow(output_title, dst);
	waitKey(0);
	return 0;
}

运行结果:
Opencv学习笔记(2)——模糊处理与形态学基本操作_第15张图片

三.形态学操作应用举例——提取水平与垂直线

1.应用原理

图像形态学操作时候,可以通过自定义的结构元素实现结构元素
对输入图像一些对象敏感、另外一些对象不敏感,这样就会让敏
感的对象改变而不敏感的对象保留输出。通过使用两个最基本的
形态学操作 – 膨胀与腐蚀,使用不同的结构元素实现对输入图像
的操作、得到想要的结果。

  • 膨胀,输出的像素值是结构元素覆盖下输入图像的最大像素值
  • 腐蚀,输出的像素值是结构元素覆盖下输入图像的最小像素值

Opencv学习笔记(2)——模糊处理与形态学基本操作_第16张图片
Opencv学习笔记(2)——模糊处理与形态学基本操作_第17张图片
Opencv学习笔记(2)——模糊处理与形态学基本操作_第18张图片

2.提取步骤

  • 输入图像彩色图像 imread
  • 转换为灰度图像 – cvtColor
  • 转换为二值图像 – adaptiveThreshold
  • 定义结构元素
  • 开操作 (腐蚀+膨胀)提取 水平与垂直线
    Opencv学习笔记(2)——模糊处理与形态学基本操作_第19张图片
    Opencv学习笔记(2)——模糊处理与形态学基本操作_第20张图片
    Opencv学习笔记(2)——模糊处理与形态学基本操作_第21张图片
    Opencv学习笔记(2)——模糊处理与形态学基本操作_第22张图片
    Opencv学习笔记(2)——模糊处理与形态学基本操作_第23张图片
    Opencv学习笔记(2)——模糊处理与形态学基本操作_第24张图片
    Opencv学习笔记(2)——模糊处理与形态学基本操作_第25张图片
    Opencv学习笔记(2)——模糊处理与形态学基本操作_第26张图片

3.程序运行

#include
#include
using namespace cv;

int main(int argc, char** argv) {
	Mat src, dst;
	src = imread("D:/photos/31.png");

	if (!src.data) {
		std::cout << "could not find image...\n";
		return -1;
	}
	char INPUT_WIN[] = "input_image";
	char OUTPUT_WIN[] = "output_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 binIma;
	adaptiveThreshold(~gray_src, binIma, 255, ADAPTIVE_THRESH_MEAN_C, THRESH_BINARY, 15, -2);
	imshow("binary_image", binIma);

	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(5,5 ),Point(-1, -1));

	Mat temp;
	morphologyEx(binIma, dst, CV_MOP_OPEN, kernel);//开操作
	//erode(binIma, temp, hline);
	//dilate(temp, dst, hline);
	bitwise_not(dst, dst);//背景变白色
	blur(dst, dst, Size(3, 3), Point(-1, -1));
	imshow("final_image", dst);
	waitKey(0);
	return 0;
}

运行结果:
Opencv学习笔记(2)——模糊处理与形态学基本操作_第27张图片

你可能感兴趣的:(视觉,opencv,c++,计算机视觉)