Search code examples
c++copencvimage-segmentationcanny-operator

segmentation of the source image in opencv based on canny edge outline attained from processing the said source image


I have a source image. I need a particular portion to be segmented from it and save it as another image. I have the canny outline of the portion I need to be segmented out,but how do I use it to cut the portion from the source image? I have attached both the source image and the canny edge outline. Please help me and suggest me a solution.

Source Image

Canny edge

EDIT-1: Alexander Kondratskiy,Is this what you meant by filling the boundary?enter image description here

EDIT-2 : according to Kannat, I have done this source Image with contour

Now how do I separate the regions that are outside and inside of the contour into two separate images?

Edit 3- I thought of 'And-ing'the mask and the contour lined source image.Since I am using C, I am having a little difficulty. this is the code I use to and:-

            hsv_gray = cvCreateImage( cvSize(seg->width, seg->height), IPL_DEPTH_8U, 1 );                       
                    cvCvtColor( seg, hsv_gray, CV_BGR2GRAY );                       
                    hsv_mask=cvCloneImage(hsv_gray);
            IplImage* contourImg =cvCreateImage( cvSize(hsv_mask->width, hsv_mask->height), IPL_DEPTH_8U, 3 );                      
            IplImage* newImg=cvCreateImage( cvSize(hsv_mask->width, hsv_mask->height), IPL_DEPTH_8U, 3 );
            cvAnd(contourImg, hsv_mask,newImg,NULL);

I always get an error of mismatch size or Type. I adjusted the size but I can't seem to adjust the type,since one(hsv_mask) is 1 channel and the others are 3 channels.

@kanat- I also tried your boundingrect but could not seem to get in right in C format.


Solution

  • Use cv::findContours on your second image to find the contour of the segment. Then use cv::boundingRect to find bounding box for this segment. After that you can create matrix and save in it cropped bounding box from your second image (as I see it is a binary image). To crop needed region use this:

    cv::getRectSubPix(your_image, BB_size, cv::Point(BB.x + BB.width/2, BB.y + BB.height/2), new_image). Then you can save new_image using cv::imwrite. That's it.

    EDIT:

    If you found only one contour then use this (else you will iterate through elements of found contours). The following code shows the steps but sorry I can't test it now:

    std::vector<std::vector<cv::Point>> contours;
    // cv::findContours(..., contours, ...);
    cv::Rect BB = cv::boundingRect(cv::Mat(contours[0]));
    cv::Mat new_image;
    cv::getRectSubPix(your_image, BB.size(), cv::Point(BB.x + BB.width/2, 
    BB.y + BB.height/2), new_image);
    cv::imwrite("new_image_name.jpg", new_image);