自定义线性滤波
- 卷积
锚点:中间的那个点,就像大海中航行的船的锚一样。
卷积作用:1,模糊图像;2,边缘查找;3,图像锐化(效果增强)。
常见算子:
- Robert算子:
沿X方向代码:
#include <opencv2/opencv.hpp>
#include <iostream>
using namespace cv;
Mat src, dst;
const char* output_title = "binary image";
int main(int argc, char** argv) {
src = imread("C:/Users/Administrator/Pictures/20160711084909.jpg");
if (src.empty()) {
printf("不能加载图像");
return -1;
}
namedWindow("input image", CV_WINDOW_AUTOSIZE);
namedWindow(output_title, CV_WINDOW_AUTOSIZE);
imshow("input image", src);
//X方向
Mat kernel = (Mat_<int>(2, 2) << 1, 0, 0, -1);//Robert算子
filter2D(src, dst, -1, kernel, Point(-1, -1), 0.0);
imshow(output_title, dst);
waitKey(0);
return 0;
}
效果:
图1-1 Robert算子沿X方向
Y方向:
//Y方向
Mat kernel_y = (Mat_<int>(2, 2) << 0, 1, -1, 0);//Robert算子
filter2D(src, dst, -1, kernel_y, Point(-1, -1), 0.0);
效果图:
图1-2 Robert算子沿y方向(左)对比x方向
- Sobel算子
Mat kernel_x = (Mat_<int>(3, 3) << -1, 0, 1, -2, 0, 2, -1, 0, 1);//Sobel算子
Mat kernel_y = (Mat_<int>(3, 3) << -1, -2, -1, 0, 0, 0, 1, 2, 1);//Sobel算子
图1-3 Sobel算子y(左)方向和x方向
- Laplace算子
Mat kernel_y = (Mat_<int>(3, 3) << 0, -1, -0, -1, 4, -1, 0, -1, 0);//Laplace算子
图1-4 Laplace算子
int c = 0;
int index = 0;
int ksize = 3;
while (true)
{
c = waitKey(500);
if ((char)c == 27)//键盘是ESC
break;
ksize = 4 + (index % 5) * 2 + 1;
Mat kernel = Mat::ones(Size(ksize, ksize), CV_32F)/(float)(ksize * ksize);
filter2D(src, dst, -1, kernel, Point(-1, -1));
index++;
imshow(output_title, dst);
}
waitKey(0);
图1-5 自定义模糊处理
其中:Mat::ones() 和 Mat::zeros()
Mat::ones()
Mat m = Mat::ones(2, 2, CV_8UC3); 相当于:Mat m = Mat(2, 2, CV_8UC3, 1);
// OpenCV replaces 1 with Scalar(1,0,0)相当于每个像素的第一个通道为1,其余两个通道为0;
Mat::zeros()
Mat m = Mat::zeros(2, 2, CV_8UC3);
//相当于创建一张黑色的图,每个像素的每个通道都为0,Scalar(0,0,0);
————————————————
版权声明:本文为CSDN博主「默茉」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/weixin_43081805/article/details/85712144
边缘处理
- API
#include<opencv2/opencv.hpp>
#include<iostream>
using namespace cv;
using namespace std;
int main(int argc, char** argv)
{
Mat src, dst;
src = imread("C:/Users/Administrator/Pictures/20160711084909.jpg");
if (!src.data)
{
cout << "无法加载图像" << endl;
return -1;
}
namedWindow("input image", CV_WINDOW_AUTOSIZE);
namedWindow("output image", CV_WINDOW_AUTOSIZE);
imshow("input image", src);
int top =(int)(0.05*src.rows);
int botton = (int)(0.05*src.rows);
int left = (int)(0.05*src.cols);
int right = (int)(0.05*src.cols);
RNG rng(12345);//其中:RNG rng(12345)是定义随机数;
int borderType = BORDER_DEFAULT;
int c = 0;
while (true) {
c = waitKey(500);
if ((char)c == 27)
break;
if ((char)c == 'r')
borderType = BORDER_REPLICATE;
else if ((char)c == 'c')
borderType = BORDER_CONSTANT;
else if ((char)c == 'w')
borderType = BORDER_WRAP;
Scalar color = Scalar(rng.uniform(0, 255), rng.uniform(0, 255), rng.uniform(0, 255));
//rng.uniform(a, b) 就是a到b中随机生存一个数。
copyMakeBorder(src, dst, top, botton, left, right, borderType, color);
imshow("output image", dst);
}
return 0;
}
borderType = BORDER_DEFAULT;
if ((char)c == 'r')
borderType = BORDER_REPLICATE;
图1-6 边缘API:BORDER_REPLICATE
else if ((char)c == 'w')
borderType = BORDER_WRAP;
图1-7 边缘API:BORDER_WRAP
else if ((char)c == 'c')
borderType = BORDER_CONSTANT;
图1-8 边缘API:CONSTANT