问题:在利用卷积模板进行卷积的时候,都会忽略边缘的像素的卷积操作。比如:使用3*3的模板进行卷积时,明显的最外面一圈的像素值没有办法位于Kernel的中心点,所以无法进行卷积操作。
解决方法:给边缘填充像素值,已满足这些点能够参与卷积运算。
API:(1)copyMakeBrder(src,dst,top,bottom,left,right,borderType,color);
其中borderType有四种类型:
1,BORDER_CONSTANT:填充边缘用指定的像素值
2,BORDER_REPLICATE:填充边缘用已知的边缘像素
3,BORDER_WRAP:填充边缘用对应的另一边的像素
4,BORDER_DEFAULT:不做操作。
至于top-right四个参数表示要填充边缘的长度。color表示要填充的颜色。
(2)GaussianBlur()也能实现边缘滤波,但是边缘类型默认是border_default,不能改变。
C++代码实现:
#include <opencv2/opencv.hpp>
using namespace std;
using namespace cv;
int main(int argv, char** argc) {
Mat src, dst;
char INPUT_WIN[] = "input image";
char OUTPUT_WIN[] = "result image";
src = imread("D:\\Pycharm\\picture\\cat.jpg");
if (!src.data) {
printf("can not open the image");
return -1;
}
namedWindow(INPUT_WIN, CV_WINDOW_AUTOSIZE);
imshow(INPUT_WIN, src);
//四种边缘填充的展示
int top = (int)(0.05*src.rows);
int bottom = (int)(0.05*src.rows);
int left = (int)(0.05*src.cols);
int right = (int)(0.05*src.cols);
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 == 'w') {
borderType = BORDER_WRAP;
}
else if ((char)c == 'c') {
borderType = BORDER_CONSTANT;
}
else {
borderType = BORDER_DEFAULT;
}
//Scalar 函数,设置补充边缘的颜色。只针对CONSTANT类型(填充指定像素值)的边缘。
Scalar color = Scalar(rng.uniform(0, 255), rng.uniform(0, 255), rng.uniform(0, 255));
copyMakeBorder(src, dst, top, bottom, left, right, borderType,color);
imshow(OUTPUT_WIN, dst);
}
//使用高斯函数实现边缘填充
GaussianBlur(src, dst, Size(5,5), 0, 0, BORDER_DEFAULT);
imshow(OUTPUT_WIN, dst);
waitKey(0);
return 0;
}