Ask Your Question

Fill the outer part of the detected contour/crop the detected contour

asked 2013-08-11 11:23:37 -0500

lenteken gravatar image

Now, I found the pupil of the fish to examine its freshness by counting the pixels on it. My first idea is to black the outer contour to count the white pixels inside the contour(pupil). The second idea is to crop the contour part I've found. But the problem is I don't how to do it. Please somebody edit my code or give me a step instruction how to do it.

image description

#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/highgui/highgui.hpp>

using namespace cv;
int main(int argc, char** argv)
RNG rng(12345);
// Load image
Mat src = imread("D:/sapsaphead.jpg");

// Invert the source image and convert to grayscale
Mat gray;
cvtColor(~src, gray, CV_BGR2GRAY);

// Convert to binary image by thresholding it
threshold(gray, gray, 220, 255, THRESH_BINARY);

// Find all contours
vector<vector<Point> > contours;
findContours(gray.clone(), contours, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_NONE);

for (int i = 0; i < contours.size(); i++)
    double area =contourArea(contours[i]);
    Rect rect = boundingRect(contours[i]);
    int radius = rect.width/2;

    // If contour is big enough and has round shape
    // Then it is the pupil
    if (area >= 30 && abs(1 - ((double)rect.width / (double)rect.height)) <= 0.2)   

         Scalar color = Scalar( rng.uniform(0, 255), rng.uniform(0,255),
rng.uniform(0,255) );
        // contour
         drawContours( src, contours, i, color, 1, 8, vector<Vec4i>(), 0, Point() );

cv::imshow("image", src);

return 0;
edit retag flag offensive close merge delete

1 answer

Sort by ยป oldest newest most voted

answered 2013-08-12 06:51:24 -0500

updated 2013-08-14 02:33:16 -0500

Basically what you want to create is a binary mask, based on the contour that you have. You already got that one. Since you apply the contour functionality on it.

// Convert to binary image by thresholding it
threshold(gray, gray, 220, 255, THRESH_BINARY);

What you can do is simply multiply the original image, with the binary image. Which will suppress all non interesting image pixels and make them black. This is called masking. Then go through the complete image.

Another approach could be to first use the boundingbox property of a contour, and apply that bounding box as a region of interest on your binary image, then only process that smaller part.

Some sample code:

You can find it here since the forum doesn't allow me to paste the code for some reason...

edit flag offensive delete link more


I am working it now for long hours but I didn't get your point. Can you please edit the code I have posted? Please

lenteken gravatar imagelenteken ( 2013-08-13 12:29:22 -0500 )edit

I will add some code sample in my answer.

StevenPuttemans gravatar imageStevenPuttemans ( 2013-08-14 02:10:49 -0500 )edit

Thanks man

lenteken gravatar imagelenteken ( 2013-08-14 02:59:34 -0500 )edit

If it suits your needs, please accept the answer, so that topic is visualised as solved.

StevenPuttemans gravatar imageStevenPuttemans ( 2013-08-14 03:08:32 -0500 )edit

I got the error. OpenCV Error: Assertion failed (points.checkVector(2)) > = 0 && (points. depth() == CV_32F || points.depth () == CV32S)) in unknown function, file ......\srcopencv\modules\imgproc\src\contours.cpp, line1895

lenteken gravatar imagelenteken ( 2013-08-14 03:26:13 -0500 )edit

I am about nothing with this information. Give us the line where it goes wrong, adapt your original code sample, and so on. Else people will just ignore your problems.

StevenPuttemans gravatar imageStevenPuttemans ( 2013-08-14 03:32:17 -0500 )edit

Question Tools


Asked: 2013-08-11 11:23:37 -0500

Seen: 5,579 times

Last updated: Aug 14 '13