Kernel 本质上是一个固定大小的数组,其中心的被称为锚点(anthor point)
卷积是kernel在每个像素上的操作;
常见算子
- Robert算子
x方向:
y方向:
通过手可以看出x与y方向差异不同提取情况,x对横向差异提取较好 y则是对垂直方向差异提取较好 - Soble算子
x方向:
y方向:
- 拉普拉斯算子(获取整个差异,能较好的获取边缘轮廓)
差异显示更加细腻
#include<opencv2/opencv.hpp>
#include <iostream>
#include <opencv2/highgui/highgui_c.h>
using namespace std;
using namespace cv;
int main(int argc, char** argv)
{
Mat src, rdst_x, rdst_y, sdst_x, sdst_y, dst;
src = imread("E://VS-pro//images//zhu.jpg");
imshow("原图", src);
//Robert X 方向
Mat rkernel_x = (Mat_<int>(2, 2) << 1, 0, 0, -1);
filter2D(src, rdst_x, -1, rkernel_x, Point(-1, -1), 0.0);
imshow("Robert X 方向 ", rdst_x);
//Robert Y 方向
Mat rkernel_y = (Mat_<int>(2, 2) << 0, 1, -1, 0);
filter2D(src, rdst_y, -1, rkernel_y, Point(-1, -1), 0.0);
imshow("Robert Y 方向 ", rdst_y);
// Sobel X 方向
Mat skernel_x = (Mat_<int>(3, 3) << -1, 0, 1, -2,0,2,-1,0,1);
filter2D(src, sdst_x, -1, skernel_x, Point(-1, -1), 0.0);
imshow("Sobel X 方向 ", sdst_x);
// Sobel Y 方向
Mat skernel_y = (Mat_<int>(3, 3) << -1, -2, -1, 0,0,0, 1,2,1);
filter2D(src, sdst_y, -1, skernel_y, Point(-1, -1), 0.0);
imshow("Sobel Y 方向 ", sdst_y);
// 拉普拉斯算子
Mat kernel = (Mat_<int>(3, 3) << 0, -1, 0, -1, 4, -1, 0, -1, 0);
filter2D(src, dst, -1, kernel, Point(-1, -1), 0.0);
imshow("拉普拉斯算子", dst);
waitKey(0);
return 0;
}
自定义kernel
//自定义
int c = 0;
int index = 0;
int ksize = 0;
while (true) {
c = waitKey(500);
if ((char)c == 27) {// ESC
break;
}
ksize = 5 + (index % 8) * 2;
Mat kernel = Mat::ones(Size(ksize, ksize), CV_32F) / (float)(ksize * ksize);//kernel随ksize的值的变化而变化
filter2D(src, dst_my, -1, kernel, Point(-1, -1));
index++;
imshow("自定义", dst_my);
}