一、添加边框
1、函数声明
在 OpenCV 中,可以使用函数 copyMakeBorder 为图像设置边界。该函数可以为图像定义额外的填充(边框),原始边缘的行或列被复制到额外的边框。该函数声明如下:
CV_EXPORTS_W void copyMakeBorder(InputArray src, OutputArray dst,
int top, int bottom, int left, int right,
int borderType, const Scalar& value = Scalar() );
src :表示输入图像,即原图像,填 Mat 类的对象即可;
dst:表示输出图像,和原图像有一样的深度
top,bottom,left,right:size=Size(src.cols +lef +right, src.rows +top+ bottom),其中 top、bottom、lefl、right分别表示在原图像的4个方向上扩充多少像素;
borderType 表示边界类型,取值如下:
enum BorderTypes {
BORDER_CONSTANT = 0,
BORDER_REPLICATE = 1,
BORDER_REFLECT = 2,
BORDER_WRAP = 3,
BORDER_REFLECT_101 = 4,
BORDER_TRANSPARENT = 5,
BORDER_REFLECT101 = BORDER_REFLECT_101,
BORDER_DEFAULT = BORDER_REFLECT_101,
BORDER_ISOLATED = 16
};
2、实例
void test04()
{
Mat src = Mat::zeros(400, 400, CV_8UC3);//创建一个窗口
Mat dst;//输出图像
int borderType = BORDER_CONSTANT;
RNG rng(12345);
int top, bottom, left, right;
top = (int)(0.05 * src.rows);
bottom = top;
left = (int)(0.05 * src.cols);
right = left;
Scalar value(rng.uniform(0, 255), rng.uniform(0, 255), rng.uniform(0, 255));
copyMakeBorder(src, dst, top, bottom, left, right, borderType, value);
imshow("111", dst);
waitKey(0);
}
二、查找轮廓
1、函数声明
1.1 findContours
在 OpenCv 中通过使用 findContours 函数,简单几个步骤就可以检测出物体的轮廓,很方便,该函数声明如下:
CV_EXPORTS_W void findContours( InputArray image, OutputArrayOfArrays contours,
OutputArray hierarchy, int mode,
int method, Point offset = Point());
/** @overload */
CV_EXPORTS void findContours( InputArray image, OutputArrayOfArrays contours,
int mode, int method, Point offset = Point());
image: 表示单通道图像矩阵,可以是灰度图,但更常用的是二值图像,一般是经过Canny、拉普拉斯等边缘检测算子处理过的二值图像;
contours: 表示轮廓的集合,用于输出轮廓集,该参数是一个向量,并且是一个双重向量,即向量内每个元素保存了一组由连续的Point点构成的点的集合的向量,每一组Point点集就是一个轮廓,有多少轮廓,向量contours 就有多少元素;
hierarchy:表示可选的输出向量,包含所抽取的图片拓扑信息,有多少条轮,hierarchy中就存放多少个元素。对于存储在contours中的第i条轮廓contours[i],向量容器 hierarchy中的元素 hierarchy[i][0]、hiearcby[i][1]、hiearchy[i][2]和 hicarchy[i][3]依次存储为和 contours[i]在同一层级结构中的上一条轮廓、下一条轮廓、下一层级结构中的子轮廓以及上一层级结构中的父轮廓的索引指数索引。如果第i条轮廓contours[i]没有上一条、下一条、父轮廓或子轮廓,则hiearchyb中的对应的元素将存储为负数。
mode: 表示轮廓提取模式,取值如下:
enum
{
CV_RETR_EXTERNAL=0,
CV_RETR_LIST=1,
CV_RETR_CCOMP=2,
CV_RETR_TREE=3
};
CV_RETR_EXTERNAL:只提取最外层的轮廓,包含在外围轮内的内围轮被忽略。
CV_RETR_LIST:检测所有的轮廓,包括内围、外围轮廓,但是检测到的轮廓不建立等级关系,彼此之间独立,没有等级关系,这就意味着这个检索模式下不存在父轮或内轮廓,所以 hierarchy 向量内所有元素的第3、第4个分量都会被置为-1。
CV_RETR_CCOMP:提取所有轮廓,并且将其组织为两层的层级结构:顶层为连通域的外围边界,次层为洞的内层边界。如果在内层洞中还有其他的轮廓,那么这个内层洞的轮廓也将被存储到顶层中。
CV_RETR_TREE:提取所有轮廓,并且构建一个嵌套式的轮廓存储
method :定义轮廓的近似方法,取值如下:
enum
{
CV_CHAIN_APPROX_NONE,
CV_CHAIN_APPROX_SIMPLE,
CV_CHAIN_APPROX_TC89_L1,
CV_CHAIN_APPROX_TC89_KCOS
};
CV_CHAIN_APPROX_NONE:保存物体边界上所有连续的轮廓点到contours 向量内。
CV_CHAIN_APPROX_SIMPLE:仅保存轮廓的拐点信息,把所有轮拐点处的点保存入contours 向量内,拐点与拐点之间直线段上的信息点不予保留。
CV_CHAIN_APPROX_TC89_L1:使用teh-Chinlchain 近似算法。
CV_CHAIN_APPROX_TC89_KCOS:使用teh-Chinlchain 近似算法。
offset :表示点的偏移量,所有的轮信息相对于原始图像对应点的偏移量,相当于在每一个检测出的轮廓点上加上该偏移量,并且Point可以是负值。
1.2 drawContours
绘制轮廓函数 drawContours 经常和査找轮廓函数 findContours 联合使用,这个好理解查找出轮廓后,通常需要把轮廓绘制出来。函数drawContours声明如下:
CV_EXPORTS_W void drawContours( InputOutputArray image, InputArrayOfArrays contours,
int contourIdx, const Scalar& color,
int thickness = 1, int lineType = LINE_8,
InputArray hierarchy = noArray(),
int maxLevel = INT_MAX, Point offset = Point() );
image: 表示目标图像;
contours: 表示输入的轮廓组,每一组轮廓出点 vector 构成;
contourIdx:指明画第几个轮廓,如果该参数为负值,就画全部轮廓;
color:为轮廓的颜色;
thickness:为轮廓的线宽,如果为负值或CV_PILLED,就表示填充轮内部;
lineType:为线型:
hierarchy:为轮廓结构信息;
maxLevel:表示绘制轮廓的最高级别,这个参数只有hierarchy有效的时候才有效,当maxLevel-0时,绘制与输入轮廓同一等级的所有轮廓,即输入轮廓和与其相邻的轮廓;当maxLcvel=1时,绘制与输入轮廓同一等级的所有轮席与其子节点;当maxLevel=2 时,绘制与输入轮廓同一等级的所有轮廓与其子节点以及子节点的子节点。
offset:表示可选轮廓偏移参数。