仅自学做笔记用,后续有错误会更改
(卷积的概念可以看看第14课)
理论
- 卷积边缘问题:从下图最右方的结果可以看出,卷积操作之后, 剩余的绿色像素部分, 我们是没有处理到的
- 那么如何处理这个问题呢:
在卷积开始之前,增加边缘像素, 填充的像素值为0 或者RGB黑色, 比如核为3*3,那么就在四周填充一个像素的边缘,这样就确保了像素的边缘被处理, 在卷积处理之后, 再去掉这些添加的边缘就行了。 openCV中有以下几种填充方法:
- BORDER_DEFAULT:将最近的像素进行映射
- BORDER_CONSTANT : 填充边缘用指定的像素值
- BORDER_REPLICATE : 复制原图中边界的行或者列
- BORDER_WRAP : 用对面的像素来补偿填充
相关API
// 给目标图像设置边框
copyMakeBorder(
- Mat src, //输入图像
- Mat dst, //输出图像
- int top, //边缘长度,一般上下左右都用同一个值
- int bottom,
- int left,
- int right,
- int borderType, //边缘类型
- Scalar value //颜色
)
代码示例
using namespace cv;
int main(int argc, char** argv){
Mat src,dst;
int ksize = 0;
src = imread(...);
if( !src.data ){
return -1;
}
//原图
char INPUT_WIN[] = "input image";
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){ //这里27是指ESC键
break;
}
if((char)c == 'r'){
borderType = BORDER_REPLICATE;
}else if((char)c == 'w'){
borderType = BORDER_WRAP;
}else if((char)c == 'c'){
borderType = BORDER_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); //注意这里的color, 只有类型是BORDER_CONSTANT的时候才会生效, 其他的类型它都没啥用
imshow("Border Demo", dst);
}*/
// 使用边框处理过后的图片, 再进行高斯模糊
Mat GaussianDst;
GaussianBlur(src, GaussianDst, Size(5,5), 0 , 0, BORDER_DEFAULT); //四种类型切换,效果就不截图了,因为区别太小了, 大家可以自己试试, 不处理边框就高斯模糊, 还有处理边框之后再进行高斯模糊, 两者的区别
imshow("GaussianBlur Image",GaussianDst);
waitKey(0);
return 0;
}
效果截图:
BORDER_DEFAULT效果:
BORDER_REPLICATE效果:
BORDER_WRAP效果:
BORDER_CONSTANT: