在实现滤波/卷积时,边界像素没有周围像素,这时候OpenCV采用的一种方法是在源图像周围添加虚拟像素,即边界外推。
cv::copyMakeBorder()就是一个为图像创建边框的函数,通过指定两幅图像,第一幅是源图像,第二幅是扩充之后的图像,同时指明填充方法,则这个函数就将第一幅图像填充后的结果保持在第二幅图像中。
void cv::copyMakeBorder(
cv::InputArray src, //源图像
cv::OutputArray dst, //扩充后图像
int top, //上扩充(大小为像素)
int bottom, //下扩充
int left, //左扩充
int right, //右扩充
int borderType, //边界外推类型
const cv::Scalar& value=cv::Scalar() //仅对constant扩充有效,指定扩充颜色,默认黑色
);
int main(int argc, char**argv) {
Mat img, dst1, dst2, dst3, dst4, dst5;
img = imread("D://somephotos//test.jpg");
namedWindow("input", cv::WINDOW_AUTOSIZE);
imshow("input", img);
copyMakeBorder(img, dst1, 30, 30, 30, 30, BORDER_CONSTANT);
copyMakeBorder(img, dst2, 30, 30, 30, 30, BORDER_REFLECT);
copyMakeBorder(img, dst3, 30, 30, 30, 30, BORDER_REPLICATE);
copyMakeBorder(img, dst4, 30, 30, 30, 30, BORDER_WRAP);
copyMakeBorder(img, dst5, 30, 30, 30, 30, BORDER_REFLECT_101);
namedWindow("CONSTANT", cv::WINDOW_AUTOSIZE);
namedWindow("REFLECT", cv::WINDOW_AUTOSIZE);
namedWindow("REPLICATE", cv::WINDOW_AUTOSIZE);
namedWindow("WRAP", cv::WINDOW_AUTOSIZE);
namedWindow("REFLECT_101", cv::WINDOW_AUTOSIZE);
imshow("CONSTANT", dst1);
imshow("REFLECT", dst2);
imshow("REPLICATE", dst3);
imshow("WRAP", dst4);
imshow("REFLECT_101", dst5);
waitKey(0);
return(0);
}
将像素放大后便于理解,每幅图像下面是每种方法的原理图,虚线表示源图像边界
边框类型 | 效果 |
cv::BORDER_CONSTANT | 复制指定的常量扩展边界 |
cv::BORDER_WRAP | 复制对边的像素扩展边界 |
cv::BORDER_REPLICATE | 复制边缘的像素扩展边界 |
cv::BORDER_REFLECT | 通过镜像复制扩展边界 |
cv::BORDER_REFLECT_101 | 通过镜像复制扩展边界,边界像素除外 |
cv::BORDER_DEFAULT | cv::BORDER_REFLECT_101的别名 |