人们轮廓的选择

时间:2018-12-13 14:09:54

标签: c++ opencv

我需要从图片中选择人物。我有一幅图像,有很多人排成一列(他们彼此不接触)。对于我的目标,我使用了imutilssome functions for image proceessing)。

我工作的算法:

我对图像进行了二值化处理,然后应用了Canny滤镜,然后使用函数cv::findContours来查找轮廓,然后从左到右对轮廓进行排序并枚举它们,但这不适用于人身上有白色衣服的人,我得到这样的东西:

result image

我该如何解决?这是我的代码:

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);

}

原始图片:

enter image description here

阈值图像反转且扩张+腐蚀的结果:

enter image description here

2 个答案:

答案 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个轮廓。您可以尝试通过本示例修改代码以适合您的需求。