opencvimage-processingcomputer-visioncontourthreshold

OpenCV: How can I remove unwanted blobs or how can I copy wanted parts into an empty image?


From the following image, how could I find the result image?

enter image description here

The images shown here are threshold images. I have tried using morphological operators but they even remove the blob I want. How could I solve this problem? Any hints?

Following is the result image I am interested to get/find:

enter image description here

import cv2
diff = cv2.imread('Image.png',0)
ret, thresh = cv2.threshold(diff, 12.5, 255, cv2.THRESH_BINARY)
thresh = cv2.dilate(thresh, None, iterations = 1)
cv2.imshow('img', thresh) # This is the  first picture I have shown
cv2.waitKey(0)

Solution

  • You are most of the way there, all you need to do now is find the blobs, add some contours and find the biggest one. Easy! below is the code in C++, ill leave it up to you to work out how to convert it to Python:

    cv::Mat mat = imread("g0cVU.png");
        Mat origImage = mat;
        Mat canny_output = mat;
        vector<vector<Point> > contours;
        vector<Vec4i> hierarchy;
        cv::Mat greyMat, colorMat;
        cv::cvtColor(mat, greyMat, CV_BGR2GRAY);
        int thresh = 100;
        RNG rng(12345);
        ///// Detect edges using canny
        Canny(greyMat, canny_output, thresh, thresh * 2, 3);
        /// Find contours
        findContours(canny_output, contours, hierarchy, CV_RETR_TREE, CV_CHAIN_APPROX_SIMPLE, Point(0, 0));
        int largest_area = 0;
        int largest_contour_index = 0;
        Rect bounding_rect;
        /// Draw contours
        Mat drawing = Mat::zeros(canny_output.size(), CV_8UC3);
        for (int i = 0; i< contours.size(); i++)
        {
            Scalar color = Scalar(rng.uniform(0, 255), rng.uniform(0, 255), rng.uniform(0, 255));
            drawContours(drawing, contours, i, color, 2, 8, hierarchy, 0, Point());
            double a=contourArea( contours[i],false);  //  Find the area of contour
           if(a>largest_area){
           largest_area=a;
           largest_contour_index=i;                //Store the index of largest contour
           bounding_rect=boundingRect(contours[i]); // Find the bounding rectangle for biggest contour
           }
        }
        rectangle(origImage, bounding_rect, Scalar(rng.uniform(0, 255), rng.uniform(0, 255), rng.uniform(0, 255)),2);
        /// Show in a window
        namedWindow("Contours", CV_WINDOW_AUTOSIZE);
        imshow("Contours", drawing);
    
        cv::namedWindow("img");
        cv::imshow("mat", mat);
        cv::imshow("mat", origImage);
        cv::imshow("mat123", drawing);
        cv::waitKey(0);
    

    Which gives this results:

    original image with contours

    Largest contour detected

    You can see in the bottom image the largest contor has a brown rectangle drawn around it.

    o and obviously once you have the largest blob (or whatever blob you deem "the correct one") you can just set everything else to black which is fairly straightforward.