我正在做一个检测拳击手套的OpenCV软件,因此我想检测并绘制仅2个最大的轮廓(每个拳击手套一个)。
我的软件为所有东西绘制轮廓,有些东西只是噪音,我不想要
我绘制轮廓的代码:
vector<vector<Point> > contours;
vector<Vec4i> hierarchy;
findContours(mBlur, contours, hierarchy, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_SIMPLE, Point(0, 0) );
//----------------------------------------------------------------------------->
vector<vector<Point> > contours_poly(contours.size());
vector<Rect> boundRect (contours.size());
vector<Point2f> boundingBoxArea(boundRect.size());
//----------------------------------------------------------------------------->
for( int i = 0; i < contours.size(); i++ )
{
approxPolyDP( Mat(contours[i]), contours_poly[i], 3, true );
boundRect[i] = boundingRect( Mat(contours_poly[i]) );
}
/// Draw polygonal contour + bonding rects
Mat drawing = Mat::zeros( range_out.size(), CV_8UC3 );
for( int i = 0; i< contours.size(); i++ )
{
Scalar color = Scalar(0,0,255);
drawContours( drawing, contours_poly, i, color, 1, 8, vector<Vec4i>(), 0, Point() );
fillPoly(drawing, contours, Scalar(255,0,0));
}
这是一个图像示例:
我的程序已经按颜色分割手套,问题在于有时由于噪音而在随机位置绘制小轮廓。当然,手套轮廓到目前为止占主导地位,这就是为什么我只想保留这些轮廓的原因。希望这能让我的问题更加清晰
请有人建议解决方案 我在C ++环境下编码 问候
答案 0 :(得分:4)
查看两个最大轮廓的最简单方法是简单地查看轮廓尺寸。这样的事情可以解决问题:
int largestIndex = 0;
int largestContour = 0;
int secondLargestIndex = 0;
int secondLargestContour = 0;
for( int i = 0; i< contours.size(); i++ )
{
if(contours[i].size() > largestContour){
secondLargestContour = largestContour;
secondLargestIndex = largestIndex;
largestContour = contours[i].size();
largestIndex = i;
}else if(contours[i].size() > secondLargestContour){
secondLargestContour = contours[i].size();
secondLargestIndex = i;
}
}
Scalar color = Scalar(0,0,255);
drawContours( drawing, contours, largestIndex, color, CV_FILLED, 8);
drawContours( drawing, contours, secondLargestIndex, color, CV_FILLED, 8);
答案 1 :(得分:2)
似乎vector<vector<Point> > contours
存储了所有轮廓。你需要做的是迭代这个向量并用它做一些算术元素,以便能够检测向量中的2个最大轮廓。
On this answer我分享了检测vector<vector<Point> >
中最大轮廓的代码,所以你就在那里。