人脸检测项目中人脸轮廓被识别为两个相同轮廓的问题
解决人脸轮廓重复检测的问题
我来帮你捋捋这个问题哈~你想要检测出单个完整的人脸轮廓,但现在每次都检测出2个,而且单独绘制这两个轮廓看起来又是同一个,这个问题大概率出在轮廓检索模式和筛选逻辑上,咱们一步步来解决:
1. 更换轮廓检索模式
你当前用的RETR_TREE会检索所有轮廓并建立完整的层级关系,很容易把人脸的外轮廓和内部的小细节轮廓(比如眼睛边缘、甚至Canny检测出的双重边缘)都当成独立轮廓捞出来。换成RETR_EXTERNAL模式就好,它只会检测最外层的轮廓,直接过滤掉内部的子轮廓,从根源减少重复:
findContours(canny_output, contours, hierarchy, RETR_EXTERNAL, CHAIN_APPROX_SIMPLE);
2. 优化轮廓筛选逻辑
你现在取前三大的轮廓,但人脸应该是画面中最大的那个目标,没必要保留三个。而且你通过判断轮廓尺寸等于前三大值来筛选,很容易把尺寸接近的冗余轮廓(比如同一个外轮廓的层级副本)加进去。改成只保留尺寸最大的那个轮廓就够了:
// 先找到尺寸最大的轮廓索引 int maxSizeIdx = 0; for (int i = 1; i < contours.size(); ++i) { if (contours[i].size() > contours[maxSizeIdx].size()) { maxSizeIdx = i; } } // 只保留符合尺寸要求的最大轮廓 if (contours[maxSizeIdx].size() >= 300) { biggestcontours.push_back(contours[maxSizeIdx]); rectangles.push_back(boundRect[maxSizeIdx]); drawContours(drawing_biggest_3, contours, maxSizeIdx, Scalar(255, 255, 255)); rectangle(drawing_biggest_3, boundRect[maxSizeIdx].tl(), boundRect[maxSizeIdx].br(), Scalar(150, 100, 255), 2); }
这样就不会把重复的轮廓误加入列表了。
3. 调整Canny阈值(可选)
如果Canny的阈值设置得太低,可能会检测出很多弱边缘,导致轮廓分裂或者重复。你可以尝试调整thresh的值(比如从50开始逐步微调),找到一个能清晰识别人脸边缘、没有冗余杂边的阈值。
另外,记得确认contours_poly和boundRect这两个变量在每帧都正确初始化了,要和contours的大小保持一致,避免出现越界或者错误赋值的情况。
内容的提问来源于stack exchange,提问作者Elio Rahy
相关产品推荐
相关产品推荐

