2015-04-17 36 views
1

我开发了一个应用程序,使用OpenCV,它检测圆形度并从二进制图像中获取质心。我现在要删除从我的原始图像中未检测到的对象。所以我想知道是否有解决方案通过质心从图像中提取对象。通过质心提取物体

这是我到目前为止有:

enter image description here

的结果进行分割: enter image description here

// Read image 
    cv::Mat im = cv::imread("11002847.bmp", cv::IMREAD_GRAYSCALE); 
    bitwise_not(im, im); 
    cv::Mat im2; 
    im.copyTo(im2); 


    //Detec the contour to get all the obeject centroid 
    std::vector<std::vector<cv::Point> > contours; 
    vector<cv::Vec4i> hierarchy; 
    findContours(im2, contours, hierarchy, CV_RETR_TREE, CV_CHAIN_APPROX_SIMPLE, cv::Point(0, 0)); 
    vector<cv::Moments> mu(contours.size()); 
    for(int i = 0; i < contours.size(); i++) 
    { 
     mu[i] = moments(contours[i], false); 
    } 
    ofstream file; 
    file.open("log.txt"); 
    /// Get the mass centers: 
    vector<cv::Point2f> mc(contours.size()); 
    for(int i = 0; i < contours.size(); i++) 
    { 
     mc[i] = cv::Point2f(mu[i].m10/mu[i].m00 , mu[i].m01/mu[i].m00); 
     file << mc[i].x << " "<< mc[i].y << endl; 
    } 
    file.close(); 


    //Dtect the circular objects and get there centroid 
    // Setup SimpleBlobDetector parameters. 
    cv::SimpleBlobDetector::Params params; 
    // Change thresholds 
    //params.minThreshold = 10; 
    //params.maxThreshold = 200; 
    // Filter by Area. 
    params.filterByArea = true; 
    params.minArea = 1; 
    // Filter by Circularity 
    params.filterByCircularity = true; 
    params.minCircularity = 0.5; 
    // Filter by Convexity 
    params.filterByConvexity = true; 
    params.minConvexity = 0.1; 
    // Filter by Inertia 
    params.filterByInertia = true; 
    params.minInertiaRatio = 0.0; 
    // Storage for blobs 
    vector<cv::KeyPoint> keypoints; 
    // Set up detector with params 
    cv::SimpleBlobDetector detector(params); 
    // Detect blobs 
    detector.detect(im, keypoints); 


    ofstream file2; 
    file2.open("log2.txt"); 

    for(vector<cv::KeyPoint>::iterator it = keypoints.begin(); it != keypoints.end(); ++it) 
    { 
     cv::KeyPoint k = *it; 
     file2 << k.pt.x << "  "<< k.pt.y << endl; 
    } 

    file2.close(); 
    // Draw detected blobs as red circles. 
    // DrawMatchesFlags::DRAW_RICH_KEYPOINTS flag ensures 
    // the size of the circle corresponds to the size of blob 
    cv::Mat im_with_keypoints; 
    drawKeypoints(im, keypoints, im_with_keypoints, cv::Scalar(0,0,255), cv::DrawMatchesFlags::DRAW_RICH_KEYPOINTS); 
    // Show blobs 
    cv::imwrite("keypoints.bmp", im_with_keypoints); 
+0

任何帮助,请。 –

回答

1

我希望我理解你的问题,但为了以防万一,我会重述它。您想要从顶部图像中删除轮廓,这些轮廓在底部图像中未被检测为关键点(即,在它们周围没有红色圆圈)。

为了对关键点的存在这样做,遍历所有的contours和检查每个轮廓使用pointPolygonTest

auto end = contours.end(); 
for (auto contour_itr = contours.begin(); contour_itr != end; ++contour_itr) { 
    auto keypoint_end = keypoints.end(); 
    for (auto keypoint_itr = keypoints.begin(); keypoint_itr != keypoint_end; ++ keypoint_itr) { 
     auto contour = *contour_itr; 
     auto keypoint = *keypoint_itr; 

     if (cv::pointPolygonTest(contour, keypoint.pt, false) > 0) { 
      // do your thing here (e.g. store contour into an array or paint it into a new image 
     } 
    } 
} 

希望帮助

+0

非常感谢你的工作。 –