我们在提取了轮廓之后我们最想做的就是把它画出来,人们还是愿意相信可以看见的东西
这个时候就将他们打印出来就可以了,提取的特征一般放在vector里
//获取轮廓:
findContours(image, //图像
contours, //轮廓点
//包含图像拓扑结构的信息(可选参数,这里没有选)
CV_RETR_EXTERNAL, //获取轮廓的方法(这里获取外围轮廓)
CV_CHAIN_APPROX_NONE); //轮廓近似的方法(这里不近似,获取全部轮廓)
//打印轮廓信息
std::cout<<"共有外围轮廓:"<<contours.size()<<"条"<<std::endl;
std::vector<std::vector<Point>>::const_iterator itContours = contours.begin();
for(;itContours != contours.end();++itContours)
{
std::cout<<"每个轮廓的长度: "<<itContours->size()<<std::endl;
}
//imshow("inverse",result_image);
//画出轮廓
Mat result(image.size(),CV_8U,Scalar(255));
//画出轮廓,参数为:画板,轮廓,轮廓指示(这里画出所有轮廓),颜色,线粗
drawContours(result,contours,-1,Scalar(0),2);
imshow("提取外围轮廓",result);
出去那些不需要的也是范围太小或者范围太大的
在这里我们定义100-1000之间的
while(it!=contours.end())
{
if (it->size()<cmin || it->size()>cmax)
it = contours.erase(it);
else
++it;
}
轮廓的描述子,其实我不明白什么是描述子,这个需要理解一下
我个人的理解就是将提取出来的特征放在一个可以描述的有规则的形状里面
百度后
描绘子(Descriptors,描述符)
表征图像特征的一系列符号或者数据,用来定性或者定量说明被描述物理的部分特性,或者图像中各部分彼此间的相互关系,为图像分析和识别提供依据。对描绘子的基本要求是尽可能对区域大小、平移与旋转的变化不敏感。在很大程度上,描述子满足一个或者多个这样的属性。描绘子包括:二值图像的几何特征和拓扑特征、二维区域描述、边界描述、纹理描述和三维物体描述。
在opencv里面给出了几种
//轮廓的形状描述子
//外接矩形
Rect r0 = boundingRect(Mat(contours[0]));
rectangle(result1,r0,Scalar(0),2);
//最小外接圆
float radius;
Point2f center;
minEnclosingCircle(Mat(contours[1]),center,radius);
circle(result1,Point(center),static_cast<int>(radius),Scalar(0),2);
//多边形估计
std::vector<Point> poly;
//参数为:输入图像的2维点集,输出结果,估计精度,是否闭合
approxPolyDP(Mat(contours[2]),poly,5,true);
std::cout<<"多边形大小:"<<poly.size()<<std::endl;
//画出结果
std::vector<Point>::const_iterator itp = poly.begin();
while(itp != poly.end()-1)
{
line(result1,*itp,*(itp+1),Scalar(0),2);
++itp;
}
//将第一个点和最后一点连起来
line(result1,*(poly.begin()),*(poly.end()-1),Scalar(128),2);
计算凸包
//std::vector<Point> hull;
//convexHull(Mat(contours[3]),hull);
//std::vector<cv::Point>::const_iterator it= hull.begin();
//while(it != (hull.end()-1))
//{
// line(result,*it,*(it+1),Scalar(0),2);
// ++it;
//}
//line(result,*(hull.begin()),*(hull.end()-1),Scalar(0),2);
最后还有一个步骤就是求出矩的信息
其实就是画出描述子的质心,(不知道理解是否正确)
//计算矩信息
it = contours.begin();
while(it != contours.end())
{
//计算所有的距
Moments mom = moments(Mat(*it++));
//计算并画出质心
circle(result1,Point(mom.m10/mom.m00,mom.m01/mom.m00),2,Scalar(2),2);
}
imshow("形状描述子",result1);
我刚做完之后我想知道到底和源图像到底差距有多大或者画出的那些描述子是不是就是规则的圆形或者矩形之类的,于是我简单打印出来这两图像的差距
Mat rr;
absdiff(result,result1,rr);
imshow("absdiff",rr);
到此为止基本上,图像的描述子和轮廓差不多就可以告一段落了