目录

​前言​

​一、调整边缘​

​1、调整的目的​

​2、调整的方式​

​1.BORDER_CONSTANT​

​2.BORDER_REPLICATE​

​3.BORDER_REFLECT​

​4.BORDER_WRAP​

​5.BORDER_REFLECT_101​

​6.BORDER_ISOLATED   ​

​二、边缘处理API-copyMakeBorder​

​1、API原型​

​2、参数​

​3、borderInterpolate​

​三、代码与结果​


前言

其实,每个内心强大的人,都有其柔弱的地方吧!也希望每个人都能越来越好,能够正视自己的柔弱,不要否定自我,也不要因此而做了错事。

坚持对的事很难,但是不要因为太难,就选择放弃。放弃很容易,但是也会让你悔恨终身。

鸡汤说完,让我们走进今天的文章吧,今天带领大家了解的是调整图像的边缘。

一、调整边缘

图像边缘这个东西,我觉得大家能够理解,就是一幅图像上下左右四个边缘,选定一定的尺寸进行修改,就是调整。

1、调整的目的

既然要调整图像边缘,我们就要弄清楚,我们调整的目的是什么?

其实调整边框就是修改边框位置的像素,在修改的过程中,我们并不会修改原有位置,而是在其外添加一定像素的边框,所以我们最重要的一个就是可以调整图像的尺寸。

我们在调整边框的过程中,可以自由设置边框的样式,所以我们也可以利用调整来美化图案,给图像添加一个独特的,锦上添花的边框。

当我们对图像做某些操作可能会修改图像的尺寸,为了修改后还能再还原回原来的大小,所以我们需要调整图像的边界。

2、调整的方式

针对不同的场景,我们调整图像边界的方式也不同,在opencv中,提供了如下几种方式:

enum BorderTypes {
BORDER_CONSTANT = 0, //!< `iiiiii|abcdefgh|iiiiiii` with some specified `i`
BORDER_REPLICATE = 1, //!< `aaaaaa|abcdefgh|hhhhhhh`
BORDER_REFLECT = 2, //!< `fedcba|abcdefgh|hgfedcb`
BORDER_WRAP = 3, //!< `cdefgh|abcdefgh|abcdefg`
BORDER_REFLECT_101 = 4, //!< `gfedcb|abcdefgh|gfedcba`
BORDER_TRANSPARENT = 5, //!< `uvwxyz|abcdefgh|ijklmno`

BORDER_REFLECT101 = BORDER_REFLECT_101, //!< same as BORDER_REFLECT_101
BORDER_DEFAULT = BORDER_REFLECT_101, //!< same as BORDER_REFLECT_101
BORDER_ISOLATED = 16 //!< do not look outside of ROI
};

这几种方式是什么意思呢?让我们分别看一下吧!假如我们有如下的一幅单通道图:

【opencv4.3.0教程】11之调整图像边缘(copyMakeBorder 与 borderInterpolate)_copyMakeBorder

 

1.BORDER_CONSTANT

这个是使用指定像素值来填充边缘,需要额外指定的像素。

如果我们指定像素值为6,那我们使用这种方式得到的边缘就是:

【opencv4.3.0教程】11之调整图像边缘(copyMakeBorder 与 borderInterpolate)_copyMakeBorder_02

当然我们在实际使用中一般都是彩色图像,所以我们指定像素一般使用Scalar类型定义。

2.BORDER_REPLICATE

这个是使用用已知的边缘像素值来填充边缘。比如顶端填充的像素,使用的就是最上面一行的像素值进行填充。如果是四个角,那就用原图像中四个角的四个像素分别赋值:

【opencv4.3.0教程】11之调整图像边缘(copyMakeBorder 与 borderInterpolate)_copyMakeBorder_03

3.BORDER_REFLECT

这个是使用用已知的边缘像素值来反转填充边缘。和上面的不同,我们四边是通过边缘对称反转填充,四个角是通过原图像四个顶点中心对称反转填充:

【opencv4.3.0教程】11之调整图像边缘(copyMakeBorder 与 borderInterpolate)_scala_04

4.BORDER_WRAP

用另外一边的像素来补偿填充,就是顶部和底部的像素互相填充,左边和右边的像素互相填充,对角的像素互相填充:

【opencv4.3.0教程】11之调整图像边缘(copyMakeBorder 与 borderInterpolate)_scala_05

 

5.BORDER_REFLECT_101

这个是使用用已知的边缘像素值来反转填充边缘。上面也有一个反转填充,这两个有什么区别呢?

我们发现这个的名字也只是在上面的基础上添加了_101,也就是说这两个是类似的。我们先看一下执行完的效果,然后大家来看一下区别:

【opencv4.3.0教程】11之调整图像边缘(copyMakeBorder 与 borderInterpolate)_copyMakeBorder_06

我想大家应该能够知道这两个的区别了,就是我们反转,上面的是使用边做反转,这里使用边界像素做反转,边界的像素是不会填充到外部边缘的。当然,这只有一个像素的差距,所以对于一个正常的图像来说,我们很难看到其细微差别。

那这种方式有什么好处呢?

一方面,我们原图像边界的像素只使用了一次,不会出现两次;另一方面,我们图像的边缘拓展更加自然。

这种方式和另外两种方式是一致的,它们分别是:BORDER_REFLECT101 BORDER_DEFAULT

 

6.BORDER_ISOLATED   

这个是使用黑色进行填充,本质上就是填充0。

【opencv4.3.0教程】11之调整图像边缘(copyMakeBorder 与 borderInterpolate)_图像边缘_07

二、边缘处理API-copyMakeBorder

opencv提供了专门的API来帮助我们进行边缘处理。

1、API原型

我们使用的API原型如下:

void copyMakeBorder( 
InputArray src,
OutputArray dst,
int top,
int bottom,
int left,
int right,
int borderType,
const Scalar& value = Scalar()
);

 

2、参数

具体的参数如下:

(1)InputArray类型的src ,输入图像。

(2)OutputArray类型的dst ,输出图像,图像的类型和输入图像相同,尺寸为:Size(src.cols+left+right, src.rows+top+bottom)。也就是在上下左右分别添加了尺寸。

(3)int类型的top,

(4)int类型的bottom,

(5)int类型的left,

(6)int类型的right,上面四个参数是图像要增加的边缘的像素大小。

(7)int类型的borderType,边缘的类型。参照 borderInterpolate。

(8)Scalar类型的value,borderType==BORDER_CONSTANT时的边界值

3、borderInterpolate

在上面,我们看到在边缘类型,他让参照borderInterpolate。具体如下:

int borderInterpolate(int p, int len, int borderType);

这个函数一般不会单独使用,一般都是上面的函数会默认调用该函数,来设置边缘。这个函数的作用是计算外推像素的源位置。也就是计算图像向外扩张的大小以及扩张的方式。

该函数的参数如下:

(1)int类型的p,沿其中一个轴外推像素的基于0的坐标,可能小于0或等于len。

(2)int类型的len,数组沿相应轴的长度。

(3)int类型的borderType,边缘的类型。除了cv::BORDER_TRANSPARENT 和 cv::BORDER_ISOLATED,当borderType==cv::BORDER_CONSTANT时,不管p和len为多少,函数总是返回-1。

三、代码与结果

接下来我们看一下代码和得到的结果。

/*
作者:水亦心
内容:core-调整图像边缘
时间:2020年5月27日
*/

#include<iostream>
#include<opencv2\opencv.hpp>

using namespace std;
using namespace cv;


int main() {

Mat YT = imread("./image/YiTian1.jpg");

if (!YT.data)
{
cout << "ERROR : could not load image.\n";
return -1;
}
imshow("倚天屠龙记", YT);

Mat YT_new;
int top = 30;
int bottom = 30;
int left = 20;
int right = 20;
copyMakeBorder(YT, YT_new, top, bottom, left, right, BORDER_CONSTANT, Scalar(21, 222, 214));
imshow("调整边框-BORDER_CONSTANT-倚天屠龙记", YT_new);

copyMakeBorder(YT, YT_new, top, bottom, left, right, BORDER_REPLICATE);
imshow("调整边框-BORDER_REPLICATE-倚天屠龙记", YT_new);

copyMakeBorder(YT, YT_new, top, bottom, left, right, BORDER_REFLECT);
imshow("调整边框-BORDER_REFLECT-倚天屠龙记", YT_new);

copyMakeBorder(YT, YT_new, top, bottom, left, right, BORDER_WRAP);
imshow("调整边框-BORDER_WRAP-倚天屠龙记", YT_new);

copyMakeBorder(YT, YT_new, top, bottom, left, right, BORDER_REFLECT_101);
imshow("调整边框-BORDER_REFLECT_101-倚天屠龙记", YT_new);

copyMakeBorder(YT, YT_new, top, bottom, left, right, BORDER_ISOLATED);
imshow("调整边框-BORDER_ISOLATED-倚天屠龙记", YT_new);

waitKey(0);
return 0;
}

得到的结果如下:


【opencv4.3.0教程】11之调整图像边缘(copyMakeBorder 与 borderInterpolate)_scala_08

原图

【opencv4.3.0教程】11之调整图像边缘(copyMakeBorder 与 borderInterpolate)_#include_09

【opencv4.3.0教程】11之调整图像边缘(copyMakeBorder 与 borderInterpolate)_边缘像素_10

【opencv4.3.0教程】11之调整图像边缘(copyMakeBorder 与 borderInterpolate)_图像边缘_11

【opencv4.3.0教程】11之调整图像边缘(copyMakeBorder 与 borderInterpolate)_边缘像素_12

【opencv4.3.0教程】11之调整图像边缘(copyMakeBorder 与 borderInterpolate)_边缘像素_13

【opencv4.3.0教程】11之调整图像边缘(copyMakeBorder 与 borderInterpolate)_图像边缘_14