# Need Help with correct approach for getting just the leaf area as image from a white background Image

Hello Everyone!

Have been struggling for some time now to get the correct approach to grap a leaf (Rice/Wheat/Grass) object over a white background. Have tried multiple approach for same and will share what I've tried so far.

Kindly note: - Leaf is not completely inside the image. - Leaf can be rotated at any angle. - Leaf may not be uniform in size as well, i.e. getting thinner at ends.

So far, have tried below approach to get the final image to include only leaf:

1. Get image, convert from RGB to BGR.
2. Convert to Grayscale
3. Apply threshold, Binary Inverse
4. Get Contours, find maximum area Contour
5. Get minimum area Rectangle from the maximum contour.
6. Find Rotation Matrix
7. Apply warpAffine
8. Get Submat.

With all these steps, the output comes to be like below:

Issue is for output Image, just the Leaf Area is needed - No White Region or Black Patches. I've tried drawing contours, but don't know how to pick exactly the contour area and save as a image.(The object not completely inside is a issues) Have also tried making the background transparent after getting the required area after applying mask, but the writing the png file with transparent background is taking too much time.

Kindly suggest if there can be simpler approach to just get the leaf area as a separate image ? I'm new to OpenCV and trying to learn more.

Code Reference Java OpenCV 3.4:

    Size kernelsize = new Size(11, 11);
//Convert Original Image to GrayScale
Imgproc.cvtColor(cameraInputImg, cameraInputImg, COLOR_RGB2BGR);
Imgproc.cvtColor(cameraInputImg, grayscale, Imgproc.COLOR_BGR2GRAY);
//Threshold the Gray Scaled Image, Change the Threshold as per required color applicable under the image.
Imgproc.threshold(grayscale, threshed, 90, 255, Imgproc.THRESH_BINARY_INV);
//Set Kernel for the Image
kernel = Imgproc.getStructuringElement(Imgproc.MORPH_ELLIPSE, kernelsize);
Imgproc.morphologyEx(threshed, morphed, Imgproc.MORPH_CLOSE, kernel);
Mat hierarchy = new Mat();
List<MatOfPoint> contours = new ArrayList<>();
Imgproc.findContours(morphed, contours, hierarchy, Imgproc.RETR_EXTERNAL, Imgproc.CHAIN_APPROX_SIMPLE);
//Check for Countours Before proceeding to find structures.
double maxArea = 0;
MatOfPoint max_contour = new MatOfPoint();
if (!contours.isEmpty()) {
//Find Max Area Contour
Iterator<MatOfPoint> iterator = contours.iterator();
while (iterator.hasNext()) {
MatOfPoint contour = iterator.next();
double area = Imgproc.contourArea(contour);
if (area > maxArea) {
maxArea = area;
max_contour = contour;
}
}
}

RotatedRect boundedLeaf = Imgproc.minAreaRect(new MatOfPoint2f(max_contour.toArray()));
Mat rotated = new Mat();
Mat cropped = new Mat();
double angle = boundedLeaf.angle;
Size rect_size = boundedLeaf.size;
double temp;
// thanks to http://felix.abecassis.me/2011/10/opencv-rotation-deskewing/
if (angle < -45.) {
angle += 90.0;
temp = rect_size.width;
rect_size.width = rect_size.height;
rect_size.height = temp;
}
// get the rotation matrix
M = Imgproc.getRotationMatrix2D(boundedLeaf.center, angle, 1);
// perform the affine transformation
Imgproc.warpAffine(cameraInputImg, rotated, M, cameraInputImg.size(), INTER_CUBIC, BORDER_CONSTANT, white);   //Refine if needed.
Imgproc.getRectSubPix(rotated, rect_size, boundedLeaf.center, cropped);


Sample Input Image:

edit retag close merge delete

Sort by » oldest newest most voted

Merging the contour contents with transparent. background is the only way, see https://answers.opencv.org/question/3... ... but if saving the result takes too much time, you are out of luck...

more

Thank you for kind response. Have tried the same, but need only green sections under the image not even the transparent background. The image will be fed to next process to pick points and process on same and should include only green data.

Having a best fit rectangle inside the contour will be exactly what I'll need and that would be huge help! Was looking at 1. https://stackoverflow.com/questions/3... 2. https://stackoverflow.com/questions/3...

With these also, will get Rotated Rectangle and getting it to Rectangle gets messy. Do we have a similar process for getting best fit rectangle inside a Contour for Java?

( 2019-11-10 05:36:05 -0500 )edit

Also, as you can see from the Output Image, there are color variation, may be close up to the image is modifying the intensity of color. I'm converting the original image from RGB to BGR before processing the same in OpenCV. Can there be any other reason for change in Color for the output... I'm afraid color variations after processing with OpenCV may lead to issues in next set of processing. Any comments ?

( 2019-11-10 05:43:23 -0500 )edit

Official site

GitHub

Wiki

Documentation