OpenCV-学习历程15- 自定义线性滤波(包含卷积的概念)(Robert+Sobel+laplace算子+自定义模糊算子)

OPENCV系列博客主要记录自己学习OPENCV的历程,以及存储已经实现的代码,以备后续回顾使用,代码中包含了主要的备注。

  一. 卷积概念:

       卷积核(也称为卷积算子)的概念: 卷积核Kernel实际上就是一个固定大小的矩阵数组,中心称为锚点;

                                 一般卷积核的维数是单数(一般是3x3或者5x5 的矩阵数组)。

       图像卷积处理: 就是将卷积核的锚点(中心点),与二维图像的每一个像素重合,然后卷积核的每一个数与其覆盖的像素相乘;

                                 并把乘积相加的结果,除以卷积核包含的数的数量,替换到二维图像,对应在卷积核的锚点位置的像素。

      常见的图像卷积的作用:模糊图像,提取边缘,图像增强锐化!

                                              根据使用卷积达到的作用不同,选用不同维度+不同结构和数据大小的卷积算子。

                        

                     

                      

                    

                   

                  

 二. 使用上边卷积算子的代码实现:

       主要需要注意: 创建kernel算子的方法:(Mat kernel= (Mat_<int>(3, 3) << 0,-1,0, -1,4,-1,0,-1,0);

                                 使用kernel算子的程序:  filter2D(src, iamge_custom,-1, custom,Point(-1,-1));

#include <opencv2/opencv.hpp>
#include <iostream>


using namespace std;
using namespace cv;


/*这个程序测试了自定义线性卷积算子,是以后边缘提取的前置内容*/
int main(int argc, char** argv) {

	//Step1 读取图片
	Mat src = imread("E:/OpenCVLearning/Project/source_image/sample.jpg"); //注意斜线方向
	if (!src.data) {
		cout << "Could not load the image ...." << endl;
		return -1;
	}

	Mat robert_x, robert_y, sobel_x, sobel_y, laplace, custom;
	Mat iamge_robert_x, iamge_robert_y, iamge_sobel_x, iamge_sobel_y, iamge_laplace, iamge_custom;

	char Input_Win[] = "Imput image";
	char Out_put_1[] = "Robert_x";
	char Out_put_2[] = "Robert_y";
	char Out_put_3[] = "sobel_x";
	char Out_put_4[] = "sobel_y";
	char Out_put_5[] = "laplace";
	char Out_put_6[] = "custom";

	//Step2 显示输入照片
	namedWindow(Input_Win,CV_WINDOW_AUTOSIZE);
	imshow(Input_Win,src);


	//Step3 Define different kernels
	//      注意!!定义算子的时候: 是按列定义算子的,而不是按行
	robert_x = (Mat_<int>(2, 2) << 1, 0, 0, -1);
	robert_y = (Mat_<int>(2, 2) << 0,-1, 1, 0);

	sobel_x = (Mat_<int>(3, 3) <<-1,-2,-1, 0,0,0,1,2,1); //sobel_x
	sobel_y = (Mat_<int>(3, 3) <<-1, 0,1,-2,0,2,-1,0,1); //sobel_y

	laplace = (Mat_<int>(3, 3) << 0,-1,0, -1,4,-1,0,-1,0);

	//Step4 使用上边的算子对图片进行卷积操作,然后显示
	//      进行卷积计算使用filter2D方法

	filter2D(src, iamge_robert_x,-1,robert_x,   Point(-1,-1),0.0);
	filter2D(src, iamge_robert_y, -1, robert_y, Point(-1, -1), 0.0);
	filter2D(src, iamge_sobel_x, -1, sobel_x,   Point(-1, -1), 0.0);
	filter2D(src, iamge_sobel_y, -1, sobel_y,   Point(-1, -1), 0.0);
	filter2D(src, iamge_laplace, -1, laplace,   Point(-1, -1), 0.0);

	//Step5 显示通过卷积计算之后的图片
	namedWindow(Out_put_1, CV_WINDOW_AUTOSIZE);
	imshow(Out_put_1, iamge_robert_x);

	namedWindow(Out_put_2, CV_WINDOW_AUTOSIZE);
	imshow(Out_put_2, iamge_robert_x);

	namedWindow(Out_put_3, CV_WINDOW_AUTOSIZE);
	imshow(Out_put_3, iamge_sobel_x);

	namedWindow(Out_put_4, CV_WINDOW_AUTOSIZE);
	imshow(Out_put_4, iamge_sobel_y);

	namedWindow(Out_put_5, CV_WINDOW_AUTOSIZE);
	imshow(Out_put_5, iamge_laplace);


	//Step6 自定义卷积模糊,并且使用循环函数,调整模糊程度
	
	int c = 0;
	int index = 0;
	int ksize = 5;
	while (true) {
		c = waitKey(500);
		if ((char)c == 27) { //esc
			break; 
		}
		ksize = 4 + (index % 5) * 2 + 1;
		custom = Mat::ones(Size(ksize, ksize), CV_32F) / (float)(ksize * ksize); //自定义卷积模糊算子的算法,在博客的图片中
		filter2D(src, iamge_custom,-1, custom,Point(-1,-1));
		index++;

		namedWindow(Out_put_6, CV_WINDOW_AUTOSIZE);
		imshow(Out_put_6, iamge_custom);
	}
	waitKey(0);
	return 0;
}

 三. 运行效果:

猜你喜欢

转载自blog.csdn.net/weixin_42503785/article/details/114109838