OpenCV处理图像边界时,采用的方法是在源图像周围添加虚拟像素。需要解决的问题就是如何对缺少相邻像素点的边缘像素点(即边界)计算出一个有效的结果。实际处理时,在没有公认方法的情况下,一般通过自定义的方式在某一场景中处理问题。
1. 自定义边框
处理图像时,只要告诉要调用的函数添加虚拟像素的规则,库函数就会自动创建虚拟像素。需要注意在创建虚拟像素时采用的方法。函数cv::copyMakeBorder()为图像创建边框。通过指定两幅图像,第一幅图像是源图像,第二幅图像是扩充之后的图像,同时指明填充方法,这个函数就会将第一幅图像填补后的结果保存在第二幅图像中。函数原型:
void cv::copyMakeBorder(
cv::InputArray src, // input image
cv::OutputArray dst, // result image
int top, // top side padding(pixels)
int bottom, // bottom side padding(pixels)
int left, // left side padding(pixels)
int right, // right side padding(pixels)
int borderType, // pixel extrapolation method
const cv::Scalar& value = cv::Scalar() // used for constant borders
);
第一个参数是源图像,第二个参数是输出图像,后面的四个参数表示边框上下左右四个方向的尺寸,参数borderType是虚拟像素填充的方式,如下:
边框填充类型 |
效果 |
cv::BORDER_CONSTANT |
使用指定的常量扩展边界,边界具有相同的值 |
cv::BORDER_WRAP |
复制对边的像素扩展边界,为每个像素分配一个距离,这个距离是像素点到源图像边缘的距离,然后将距离对边相同距离的像素的值赋予对应的边框像素 |
cv::BORDER_REPLICATE |
复制边缘的像素扩展边界,将源图像以外的像素全部赋值为图像边缘像素的值 |
cv::BORDER_REFLECT |
通过镜像复制扩展边界,为边框的每个像素赋值了源图像内距离同一边界n对应的像素点得值 |
cv::BORDER_REFLECT_101 |
通过镜像赋值扩展边界,边界像素除外,为边框内每个像素赋值了源图像内距离同一边界n+1对应的像素点的值。大多数情况下,该值是默认选项,cv::BORDER_DEFALT对应的是cv::BORDER_REFLECT_101 |
参考下图理解上个参数的含义:
如下图是边缘处的像素值,更直观的显示borderType取不同值时的情况:
2. 自定义外推
某些情况下,需要计算某一特定像素所参考的像素的位置。比如,给定一幅宽为w,高位h的图像,需要知道用哪个像素为虚拟像素赋值。这个操作是外推的,使用函数cv::borderInterpolate()实现。函数原型:
int cv::borderInterpolate( // returns coordinate of donor pixel
int p, // 0-based corrdinate of extrapolated pixel
int len, // length of array (on relevant axis)
int borderType // pixel axtrapolation method
);
该函数一次计算一个维度上的外推,这个函数的输入是一个坐标p,一个长度len(关联方向上的图像的实际大小)以及一个边界类型。比如,可以在混合的边界条件下计算一个特定像素的值,在一维中使用cv::BORDER_REFLECT_101,在另一个维度中使用cv::BORDER_WRAP。如下:
int nRow = cv::borderInterpolate(100, srcImg.rows, cv::BORDER_REFLECT_101);
int nCol = cv::borderInterpolate(-6, srcImg.cols, cv::BORDER_WRAP);
cv::Vec3b val = srcImg.at<cv::Vec3b>(nRow, nCol);
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/46154.html