给图片加边框
原理
在卷积的过程中,图片边缘的处理总是一个问题。因为卷积核的锚点无法覆盖图片的边缘像素,硬要覆盖的话,卷积核就会有一部分超出图片的范围。
OpenCV中的大部分方法都会将图片的边缘像素进行扩充,从而扩大原有的图片。这样卷积核就能覆盖原来的边缘像素了。
本文将介绍两种对图片边缘像素进行扩充的方法:
- BORDER_CONSTANT:用一个常量(比如表示黑色的0)对图片边缘进行扩充
- BORDER_REPLICATE:图片的边缘像素被复制,从而形成图片的边框
API
以上两种边缘扩充的方法都可以用copyMakeBorder()
函数来实现,其函数原型如下:
cpp
void cv::copyMakeBorder(InputArray src, //输入图片
OutputArray dst, //输出图片
int top, //上边框宽度
int bottom, //下边框宽度
int left, //左边框宽度
int right, //有边框宽度
int borderType, //边框扩充类型
const Scalar& value = Scalar()); //如果扩充类型是BORDER_CONSTANT,这个参数用来指定常量
实例
这个例子分别用第一节讲的两种方法给图片扩充边框:
- 上下边框的宽度为原图高度的5%,左右边框的宽度为原图宽度的5%;
- 用常量扩充边框时,边框的颜色随机生成
完整代码如下:
cpp
#include <opencv2/imgproc.hpp>
#include <opencv2/imgcodecs.hpp>
#include <opencv2/highgui.hpp>
using namespace cv;
int main() {
Mat src{ imread("lena.jpg") };
int top{ static_cast<int>(0.05 * src.rows) }, bottom{ top }; //初始化上下边框的宽度
int left{ static_cast<int>(0.05 * src.cols) }, right{ left }; //初始化左右边框的宽度
RNG rng{ 12345 }; //随机数生成器
//常量边框
Scalar value(rng.uniform(0, 255), rng.uniform(0,255), rng.uniform(0, 255)); //生成随机的BGR颜色
Mat const_border;
copyMakeBorder(src,
const_border,
top,
bottom,
left,
right,
BORDER_CONSTANT,
value); //需要指定value参数
//复制边框
Mat rep_border;
copyMakeBorder(src,
rep_border,
top,
bottom,
left,
right,
BORDER_REPLICATE); //注意这里并没有value这个参数
imshow("原图", src);
imshow("常量边框", const_border);
imshow("复制边框", rep_border);
waitKey(0);
}
运行结果如下: