Question

I am having a problem with this project of mine implemented using JavaCV. I want to find at least, the top-most, bottom-most, left-most and right-most points in a binary image:

Happy Mouth Binary image

Points I mean here are (x,y) coordinates. I have tried implementing HoughLines (it only detects lines but not the curves) and cvFindContours but I just can't extract the coordinates properly. I'm still a novice, if only I know what is the value of the white lines as well as the background, then maybe I could just loop around the image.

Is there an easier way out? Thank you very much for any help.

Was it helpful?

Solution

You can use a loop here to find the most left, right, top and bottom points. However, you need to think on how to make a smart loop. You could just loop through all pixels, but you could also use a smarter approach. For instance, the left most point is probably somewhere on the left. So if you use a scanline which goes from left to right you might be more likely to find this pixel than if you would just scan top->bottom. This being said, it is quite easy to get the values from an image.

Let's say we have an image binaryImg with n channels. In case of a gray scale image n should be 1, but in case of a color image n should be 3. Let's say we have the indices 0 <= y < height, 0 <= x < width and 0 <= k < n. We can the value of a pixel(x, y) as follows:

((uchar *)(binaryImg->imageData + y*binaryImg->widthStep))[x*binaryImg->nChannels + k]

Since a gray image has only a single channel, we can check if a pixel is white using:

((uchar *)(binaryImg->imageData + y*binaryImg->widthStep))[x] == 255

In terms of speed, this solution will give a worst case time of O(n), but in practice you will not have to look through all pixels.

OTHER TIPS

If you have a vector of points like std::vector<cv::Point2f> pts then you can use opencv cv::boundingRect method which computes the up-right bounding rectangle of your point set. Use it like this:

// this is your set of floating point (filled vector)
std::vector<cv::Point2f> pts;
// convert to matrix
cv::Mat ptsmat(pts);
// compute the bounding rectangle 
cv::Rect bbox = cv::boundingRect(ptsmat);

I used c++ opencv api but you could use corresponding function in javacv

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top