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;
}
三. 运行效果: