Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to get size of an area in JavaCV

In my project I want to get the size from the greatest homogeneous area of a specific color (in my example below it's the blue sky).

My first idea is to convert the orginal image:

original image

to an binary image, detect the skycolor and create a mask with this area: mask image

But how can I get the size and the position of these white pixels? I want a efficient method, which says true, if the picture has a blue sky in the upper 1/3 of the picture. Any ideas? Should I create a "global mask" (see image 3 in comment) and compare it with the binary picture? Or is there an easier way?

Thank you.

like image 846
501 - not implemented Avatar asked Jun 26 '12 16:06

501 - not implemented


People also ask

How to find the size of an array in Java?

There is no size () method available with the array. But there is a length field available in the array that can be used to find the length or size of the array. array.length: length is a final variable applicable for arrays.

How to get length of array[] in Java using length variable?

With the help of the length variable, we can obtain the size of the array. Examples: int size = arr[].length; // length can be used // for int[], double[], String[] // to know the length of the arrays. Below is the illustration of how to get the length of array[] in Java using length variable: Example 1:

What is map size in Java with example?

Map size () Method in Java With Examples. Map size () method in Java is used to get the total number entries i.e, key-value pair. So this method is useful when you want total entries present on the map. If the map contains more than Integer.MAX_VALUE elements return Integer.MAX_VALUE.

How much memory does an object have in Java?

This is 16 bits as it is only storing the address of the object as there is no user defined constructor. Same is the case if we use an default object using the Object class of Java: Hence, any object has two components for memory: Similarly, you can use this method to calculate the size of any object in Java instantly.


1 Answers

The algorithm is the following:

  1. Convert input image to YCbCr color space which is good to detect blue (and also red) color: YCrCb image To convert some image to another color space use cvtColor.
  2. Extract blue channel from it: Blue image Use function extractChannel to extract needed channel.
  3. Detect regions with biggest value [0-255] of blue color. I used function minMaxIdx and then just multiplied maximum on 0.8 (this is threshold). You can use more complex methods like histogram analysation.
  4. Make a mask of blue color: binary For this I used threshold function with calculated in step 3 threshold (as parameter).
  5. Find all blue contours in mask. In OpenCV it's easy - just use findContours.
  6. And, finally, detect contour with biggest square and find its coordinates (center). To calculate contour with biggest square you can use function contourArea.

Also instead of steps 1-4 you can convert image to HSV and using inRange detect blue color.

Here's my c++ impementation:

Mat inMat = imread("input.jpg"), blueMat, threshMat;

cvtColor(inMat, blueMat, CV_BGR2YCrCb);//convert to YCrCb color space

extractChannel(blueMat, blueMat, 2);//get blue channel

//find max value of blue color
//or you can use histograms
//or more complex mathod
double blueMax;
minMaxIdx(blueMat, 0, &blueMax);

blueMax *= 0.8;
//make binary mask
threshold(blueMat, threshMat, blueMax, 255, THRESH_BINARY);

//finding all blue contours:
vector<vector<Point> > contours;
vector<Vec4i> hierarchy;
findContours(blueMat, contours, hierarchy, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_SIMPLE);

double maxSquare = 0;
vector<Point> maxContour;
//finding contours with biggest square:
for (size_t i=0; i<contours.size(); i++)
{
    double square = contourArea(contours[i]);
    if (square > maxSquare)
    {
        maxContour = contours[i];
        maxSquare = square;
    }
}

//output results:
Point center = centerPolygon(maxContour);
cout << "square = " << maxSquare << endl;
cout << "position: x: " << center.x << ", y: " << center.y << endl;

Here's centerPolygon function:

Point centerPolygon(const vector<Point>& points)
{
    int x=0, y=0;

    for (size_t i=0; i<points.size(); i++)
    {
        x += points[i].x;
        y += points[i].y;
    }

    return Point(x/points.size(), y/points.size());
}

The output of program is next:

square = 263525
position: x: 318, y: 208

You can convert this code to JavaCV - see this tutorial.

like image 178
ArtemStorozhuk Avatar answered Oct 06 '22 04:10

ArtemStorozhuk