卷积
- 应用:主要用于模糊图像(降噪),提取边缘,增强图像
- 卷积是图像处理中的一个操作,是kernel在图像的每个像素上的操作
- kernel本质上是一个固定大小的矩阵数组,其中心点成为锚点(anchor point)
卷积算子(掩模)
API
用小矩阵定义一个Mat对象
Mat kernel =(Mat<type>(row,column)<< , , , , , , );
例如
Mat kernel = (Mat_<int>(2, 2) << 1, 0, 0, -1);
filter2D
定义
filter2D( InputArray src, OutputArray dst, int depth,
InputArray kernel, Point anchor=Point(-1,-1),
double delta=0, int borderType=BORDER_DEFAULT );
例如
filter2D(src, dst, -1, kernel, Point(-1, -1));
参数:depth一般取-1
matlab风格的创建对象的方法:zeros,ones
Mat z =Mat::zeros(2,2, CV_8UC1);
Mat o =Mat::ones(2,2 ,CV_32F);
zero:像素值全为0,定义一张全黑的图片
ones:像素值全为1
代码演示
#include<opencv2/opencv.hpp>
#include<iostream>
using namespace cv;
int main(int argc, char** argv)
{
Mat src, dst, robert_x, robert_y, sobel_x, sobel_y, laplace,blur;
src = imread("D:/vcprojects/shuanggaosi.jpg");
if (!src.data)
{
printf("could not laod image...\n");
return -1;
}
namedWindow("src", WINDOW_AUTOSIZE);
imshow("src", src);
//Robert算子x方向
Mat kernel = (Mat_<int>(2, 2) << 1, 0, 0, -1);
filter2D(src, robert_x, -1, kernel, Point(-1, -1));
namedWindow("robert_x result", WINDOW_AUTOSIZE);
imshow("robert_x result", robert_x);
//Robert算子y方向
Mat kernel2 = (Mat_<int>(2, 2) << 0,1,-1,0);
filter2D(src, robert_y, -1, kernel2, Point(-1, -1));
namedWindow("robert_y result", WINDOW_AUTOSIZE);
imshow("robert_y result", robert_y);
//sobel算子x方向
Mat kernel3 = (Mat_<int>(3,3) << -1,0,1,-2,0,2,-1,0,1);
filter2D(src, sobel_x, -1, kernel3, Point(-1, -1));
namedWindow("sobel_x result", WINDOW_AUTOSIZE);
imshow("sobel_x result", sobel_x);
//sobel算子y方向
Mat kernel4 = (Mat_<int>(3, 3) << -1,-2,-1,0,0,0,1,2,1);
filter2D(src, sobel_y, -1, kernel4, Point(-1, -1));
namedWindow("sobel_y result", WINDOW_AUTOSIZE);
imshow("sobel_y result", sobel_y);
//拉普拉斯算子
Mat kernel5 = (Mat_<int>(3, 3) << 0,-1,0,-1,4,-1,0,-1,0);
filter2D(src, laplace, -1, kernel5, Point(-1, -1));
namedWindow("laplace result", WINDOW_AUTOSIZE);
imshow("laplace result", laplace);
//自定义线性滤波
int c = 0;
int ksize = 0;
int index = 0;
while (true)
{
c = waitKey(500);
if (char(c) == 27)//27是键盘上ESC键
break;
ksize = (index % 4) * 2 + 3;
index++;
Mat kernel6 = Mat::ones(ksize, ksize, CV_32F)/(float)(ksize*ksize);
filter2D(src, blur, -1, kernel6, Point(-1, -1));
namedWindow("blur result", WINDOW_AUTOSIZE);
imshow("blur result", blur);
}
waitKey(0);
return 0;
}
结果
原图
是一个动态的模糊过程