Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Automatic approach for removing colord object shadow on white background?

I am working on some leaf images using OpenCV (Java). The leaves are captured on a white paper and some has shadows like this one:

enter image description here

Of course, it's somehow the extreme case (there are milder shadows).

Now, I want to threshold the leaf and also remove the shadow (while reserving the leaf's details).


My current flow is this:

1) Converting to HSV and extracting the Saturation channel:

Imgproc.cvtColor(colorMat, colorMat, Imgproc.COLOR_RGB2HSV);
ArrayList<Mat> channels = new ArrayList<Mat>();
Core.split(colorMat, channels);
satImg = channels.get(1);

2) De-noising (median) and applying adaptiveThreshold:

Imgproc.medianBlur(satImg , satImg , 11);
Imgproc.adaptiveThreshold(satImg , satImg , 255, Imgproc.ADAPTIVE_THRESH_MEAN_C, Imgproc.THRESH_BINARY, 401, -10);

And the result is this:

enter image description here

It looks OK, but the shadow is causing some anomalies along the left boundary. Also, I have this feeling that I am not using the white background to my benefit.

Now, I have 2 questions:
1) How can I improve the result and get rid of the shadow?

2) Can I get good results without working on saturation channel?. The reason I ask is that on most of my images, working on L channel (from HLS) gives way better results (apart from the shadow, of course).


Update: Using the Hue channel makes threshdolding better, but makes the shadow situation worse:

enter image description here


Update2: In some cases, the assumption that the shadow is darker than the leaf doesn't always hold. So, working on intensities won't help. I'm looking more toward a color channels approach.

like image 415
Mahm00d Avatar asked Dec 12 '13 11:12

Mahm00d


People also ask

How to remove the white background from an image?

Easily remove the white background of your photos in seconds with our free online tool. Download your new image or open it in Creative Cloud Express to turn it into a stunning graphic. How to remove the white background from an image. 1. Select. For best results, choose an image where the subject has clear edges with nothing overlapping. 2. Remove.

How does the background removal add-on work?

Even if the object in the original photograph has a shadow, the Background Removal Add-On will remove that shadow, enabling you to add a consistent shadow location and size for all your product images. Below is the transformation used for the far right image shown above: :

How to fill in shadow area with white?

You could use the path tool to go around the shadow area, convert the path to a selection and fill it with white. Show activity on this post. Really, all you can do is zoom in and use a brush on a mask.

How do I add shadows to my product images?

A fully transparent background makes it easy to add shadows. Even if the object in the original photograph has a shadow, the Background Removal Add-On will remove that shadow, enabling you to add a consistent shadow location and size for all your product images. Below is the transformation used for the far right image shown above: :


2 Answers

I don't use opencv, instead I was trying to use matlab image processing toolbox to extract the leaf. Hopefully opencv has all the processing functions for you. Please see my result below. I did all the operations in your original image channel 3 and channel 1.

First I used your channel 3, threshold it with 100 (left top). Then I remove the regions on the border and regions with the pixel size smaller than 100, filling in the hole in the leaf, the result is shown in right top.

Next I used your channel 1, did the same thing as I did in channel 3, the result is shown in left bottom. Then I found out the connected regions (there are only two as you can see in the left bottom figure), remove the one with smaller area (shown in right bottom).

enter image description here

Suppose the right top image is I1, and the right bottom image is I, the leaf is extracted by implement ~I && I1. The leaf is:

enter image description here

Hope it helps. Thanks

like image 160
lennon310 Avatar answered Oct 19 '22 19:10

lennon310


I tried two different things: 1. other thresholding on the saturation channel 2. try to find two contours: shadow and leaf

I use c++ so your code snippets will look a little different.

trying otsu-thresholding instead of adaptive thresholding:

cv::threshold(hsv_imgs,mask,0,255,CV_THRESH_BINARY|CV_THRESH_OTSU);

leading to following images (just OTSU thresholding on saturation channel):

enter image description hereenter image description here

the other thing is computing gradient information (i used sobel, see oppenCV documentation), thresholding that and after an opening-operator I used findContours giving something like this, not useable yet (gradient contour approach):

enter image description hereenter image description here

like image 45
Micka Avatar answered Oct 19 '22 20:10

Micka