我需要从图片中选择人物。我有一幅图像,有很多人排成一列(他们彼此不接触)。对于我的目标,我使用了imutils
(some functions for image proceessing)。
我工作的算法:
我对图像进行了二值化处理,然后应用了Canny滤镜,然后使用函数cv::findContours
来查找轮廓,然后从左到右对轮廓进行排序并枚举它们,但这不适用于人身上有白色衣服的人,我得到这样的东西:
我该如何解决?这是我的代码:
int main() {
std::cout << "Hello, World!" << std::endl;
sorting_contours();
return 0;}
void sorting_contours() {
Mat image = imread("6.jpg");
Mat orig = image.clone();
Mat gray;
cvtColor(image, gray, CV_BGR2GRAY);
threshold(gray, gray, 245, 255, CV_THRESH_BINARY);
Mat edged = imutils::auto_canny(gray);
vector<Vec4i> hierarchy;
vector<vector<Point>> contours;
cv::findContours(edged, contours, hierarchy, CV_RETR_EXTERNAL,
CV_CHAIN_APPROX_SIMPLE);
vector<Rect> boundRect;
contours = imutils::sort_contours(contours, boundRect, imutils::SortContoursMethods::left_to_right);
Mat sortedImage = image.clone();
for (int i = 0; i < contours.size(); i++) {
sortedImage = imutils::label_contour(sortedImage, vector<vector<Point> >(1, contours[i]), i,
cv::Scalar(240, 0, 159));
}
imshow("left_to_right", sortedImage);
waitKey(0);
}
原始图片:
阈值图像反转且扩张+腐蚀的结果:
答案 0 :(得分:1)
仅考虑findcontours返回的层次结构中的外部轮廓。
答案 1 :(得分:0)
您的初始代码有两个错误。第一个是图像期望源是黑色背景中的白色物体,但是您却相反。这样做很容易解决:
image = 255 - image; // this is the image you already thresholded
然后它还有另一个问题,它给您折线。那是因为您正在传递精巧的图像,该图像不一定具有连续线。更甚者,您可以使用自动模式,这可能不错,但不一定完美。以下示例对我有用:
// load data and threshold it
cv::Mat image = cv::imread(R"(a.jpg)"), gray;
cv::cvtColor(image, gray, CV_BGR2GRAY);
cv::threshold(gray, gray, 210, 255, CV_THRESH_BINARY);
// invert the image
gray = 255 - gray;
// close the gaps this is equivalent to dilate+erode
cv::Mat element = cv::getStructuringElement(cv::MORPH_ELLIPSE, cv::Size(9, 9), cv::Point(4, 4));
cv::morphologyEx(gray, gray, cv::MORPH_CLOSE, element);
// get the contours
std::vector<cv::Vec4i> hierarchy;
std::vector<std::vector<cv::Point>> contours;
cv::findContours(gray, contours, hierarchy, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_SIMPLE);
std::cout << "Found " << contours.size() << " contours" << std::endl;
这将恰好返回4个轮廓。您可以尝试通过本示例修改代码以适合您的需求。