加强版 第五节图像处理与视频分析
基本概念
图像轮廓
主要针对二值图像,轮廓是一系列点
vector<vector<Point>xxx用于存储多个点
vector<Vec4i>xxx包含四个整数,分别代表下一个轮廓的索引,上一个轮廓的索引,一个子轮廓的索引和父轮廓的索引
相关API
1. 功能基本描述
• findContours函数的主要目的是在二值图像中找到物体的轮廓。比如,你有一张简单的黑白图像,黑色部分是背景,白色部分是一个圆形。这个函数就能找到这个圆形的轮廓,也就是圆形和背景的边界。
2. 参数一般解释
• 输入图像:必须是单通道的二值图像。这是因为函数需要明确地区分物体和背景。例如,图像像素值为0表示背景,255表示物体,这样函数才能沿着物体和背景的边界去寻找轮廓。
• 轮廓存储容器:用来接收找到的轮廓信息。假设你要在一个包含多个形状的图像中找到所有形状的轮廓,这个容器就会把每个形状的轮廓点信息都存储起来,每个轮廓是一系列的点。
• 层次结构容器:用于记录轮廓之间的层次关系。例如,在一幅有大矩形里面套着小矩形的图像中,大矩形和小矩形的轮廓是有层次关系的,这个容器就存储这种关系,像是小矩形轮廓属于大矩形轮廓内部这种信息。
• 检索模式:不同的检索模式有不同的用途。例如,除了RETR_TREE模式外,还有RETR_EXTERNAL模式。RETR_EXTERNAL模式只查找最外层的轮廓,适用于只关心图像中最外面物体轮廓的情况,比如在只需要找到图像中最大物体的外边界时就很有用。
{
1. RETR_EXTERNAL
• 含义:只检索最外层的轮廓。例如,在一幅包含多个嵌套形状(如一个大圆形里面有小圆形)的图像中,它只会找到大圆形的轮廓,而忽略内部小圆形的轮廓。
• 应用场景:当你只关心图像中最主要物体的外边界,或者想排除内部细节时很有用。比如在对一张有很多小图案的商标图片进行处理时,只想找到商标的外轮廓,就可以使用这种模式。
2. RETR_LIST
• 含义:检索所有轮廓,但不建立任何层次关系。所有轮廓都被看作是在同一层次上,没有父子、嵌套等关系。
• 应用场景:适用于不需要考虑轮廓之间层次结构,只是简单地想要获取所有轮廓信息的情况。例如,在统计图像中所有独立形状的数量,并且不关心它们是否嵌套时可以使用。
3. RETR_CCOMP
• 含义:检索所有轮廓,并将它们组织成两级层次结构。顶层是外轮廓,第二层是内轮廓(洞)。例如,在一个有空心形状的图像中,它能区分出外部轮廓和内部的空心部分轮廓。
• 应用场景:用于处理有简单嵌套关系(如空心图形)的图像,并且只需要区分外层和内层轮廓这种两级层次的情况。
4. RETR_TREE
• 含义:检索所有轮廓,并建立完整的层次结构。它可以表示复杂的轮廓关系,包括嵌套、相邻等多种情况。像在有多个形状相互嵌套、包含多个层次的复杂图像中,能很好地描述轮廓之间的关系。
• 应用场景:适用于需要详细分析轮廓之间复杂关系的情况,如在对具有多个嵌套图形的工程图纸进行分析,或者对包含复杂形状的自然场景图像进行处理时。
}
• 轮廓近似方法:可以选择不同的近似方式来简化轮廓信息。比如CHAIN_APPROX_NONE模式会存储轮廓上的所有点,而CHAIN_APPROX_SIMPLE模式会对轮廓进行简化,像直线部分只保留端点,这样可以减少存储轮廓所需的数据量,同时又能保持轮廓的基本形状。
{
1. CHAIN_APPROX_NONE
• 含义:存储轮廓上的所有点。这种方法会精确地记录轮廓经过的每一个像素点,不会对轮廓进行任何简化。
• 应用场景:在需要高精度地描绘轮廓,或者后续操作对轮廓细节要求极高的情况下使用。例如,对于一些需要精确测量轮廓长度,且轮廓形状不规则、细节丰富的图像,使用这种方法可以保留完整的轮廓信息。
2. CHAIN_APPROX_SIMPLE
• 含义:压缩水平、垂直和对角线段,只保留它们的端点。这是一种常用的近似方法,它可以在不丢失轮廓基本形状的前提下,大大减少存储轮廓所需的数据量。
• 应用场景:适用于大多数情况,特别是当轮廓中有较多直线段时。例如,在处理简单几何形状(如矩形、三角形)或者具有明显直线边界的物体轮廓时,这种方法既能有效表示轮廓,又能减少数据存储和后续处理的复杂度。
3. CHAIN_APPROX_TC89_L1和CHAIN_APPROX_TC89_KCOS
• 含义:这两种方法是使用 Teh - Chin 链近似算法的不同形式。它们也是对轮廓进行近似,但具体的近似方式是基于特定的数学算法。
• 应用场景:在一些对轮廓近似精度有特殊要求,且希望通过特定算法来实现近似的情况下可以使用。不过相对来说,这两种方法在日常应用中没有前两种那么普遍。
}
• 偏移量:用于对轮廓的位置进行调整。例如,如果需要将找到的轮廓在图像中的位置整体向右和向下移动一定的像素量,就可以通过设置这个偏移量来实现。
drawContours是 OpenCV 中的一个函数,用于在图像上绘制轮廓。
1. 功能描述:
• 它可以将找到的轮廓以特定的颜色、线宽等属性绘制在给定的图像上,使得轮廓在图像中清晰可见,方便用户进行可视化分析和处理。
2. 参数解释:
• 图像参数:第一个参数是要在其上绘制轮廓的图像,通常是一个Mat对象。
• 轮廓容器参数:第二个参数是包含要绘制轮廓的容器,一般是vector<vector<Point>>类型,每个内部的向量表示一个轮廓,由一系列的点组成。
• 轮廓索引参数:第三个参数可以是一个整数索引或者特殊值(如 -1)。如果是整数索引,则只绘制指定索引对应的轮廓;如果是 -1,则绘制所有的轮廓。
• 颜色参数:第四个参数是一个Scalar对象,用于指定绘制轮廓的颜色。例如Scalar(0, 0, 255)表示红色,Scalar(255, 0, 0)表示蓝色等。
• 线宽参数:第五个参数指定绘制轮廓的线宽。较大的值会使轮廓线更粗,较小的值则使轮廓线更细。
• 连接方式参数:第六个参数一般情况下不太常用,它指定了轮廓如何连接线段,不同的值可能会有不同的连接效果,但一般使用默认值即可。
#include<opencv2/opencv.hpp>
#include<iostream>
using namespace cv;
using namespace std;
int main(int argc, char** argv) {
Mat sgv,stu,sbt;
Mat stv = imread("C:/newword/image/3.png");
if (stv.empty()) {
printf("no pc");
return -1;
}
namedWindow("abc", WINDOW_AUTOSIZE);
imshow("abc", stv);
GaussianBlur(stv,sgv,Size(3,3),0);
cvtColor(sgv, sbt, COLOR_BGR2GRAY);
threshold(sbt, stu, 0, 255, THRESH_BINARY | THRESH_OTSU);
vector<vector<Point>>contours;
vector<Vec4i>hierarchy;
findContours(stu, contours, hierarchy, RETR_TREE, CHAIN_APPROX_SIMPLE, Point());
drawContours(stv, contours, -1, Scalar(0, 0, 255), 2, 8);
// for (size_t t = 0; t < contours.size(); t++) {
drawContours(stv, contours, t, Scalar(0, 0, 255), 2, 8);
}
imshow("asdd", stv);
waitKey(0);
destroyWindow;
return 0;
}