What I would like to do is take an image of several plants and remove the background lines and noise from the image. The end result will then hopefully be able to be turned into a binary image where every 1 value is just part of the plant. Is there any way for me to do this automatically without having to use a manual threshold? One solution I've looked into is just estimating the value of what is not noise and then subtracting, but this results in removing parts of plants. An example image for input is: https://i.stack.imgur.com/jJVv7.png
Asked
Active
Viewed 3,098 times
3
-
I'd convolute with gaussian to remove the speckles and then do some edge detection – NeplatnyUdaj Dec 17 '13 at 17:00
-
@NeplatnyUdaj That seems rather [convoluted](http://english.stackexchange.com/a/64047), perhaps first convolve with a Gaussian. ;) – chappjc Dec 17 '13 at 18:09
-
Yep. Convolve is the right word. Every day I learn something new :) Thanks – NeplatnyUdaj Dec 17 '13 at 18:22
2 Answers
3
I=im2bw(I,graythresh(I));
imshow(I)

lennon310
- 12,503
- 11
- 43
- 61
-
-
I may need to post a second question, but I don't know if this is also an easy to answer question: Is it possible to go as far as marking each leaf in the image? I know approximately how it should look, and I know where each plant is now. – Sam Dec 17 '13 at 17:16
-
Try C=bwconncomp(I); I1=zeros(size(I)); I1(C.PixelIdxList{k})=I(C.PixelIdxList{k}); I1 will display you only one leaf then. In your case k is the number from 1 to 17. Since some of your leafs are not connected, so the total number of k is slightly larger than your leaf number 14. – lennon310 Dec 17 '13 at 17:32
-
That gives me one plant. What I want to do is get each leaf for each plant. I was thinking maybe finding a way to find the tip of each leaf using the points of each curve for the plant? then I know that a leaf is approximately elliptical so I could expand from there. – Sam Dec 17 '13 at 17:42
-
sorry i confused plant and leaf as one same thing. To extract the leaf is challenging because you don't have other evident feature in the image. The intensities of the leafs are all around 255. I tried I=double(I); I1=I.*(I>253); imshow(uint8(I1)), to fall apart the leafs in each plant, but it doesn't work for every plant. – lennon310 Dec 17 '13 at 17:56
0
Segment each leaf is not an easy task since the boundaries are not that clear. The solution shown below segment a few leafs, but not all of them. It's a simple solution that may be a good start point.
The algorithm, implemented using Marvin Framework:
- Invert the image colors
- Binarize
- Morphological Erosion
- Morphological dilation
Below the original image, binary image and some leafs segmented.
Source code:
public class RemoveBackground {
public RemoveBackground(){
// 1. Load plug-ins
MarvinImagePlugin erode = MarvinPluginLoader.loadImagePlugin("org.marvinproject.image.morphological.erosion");
MarvinImagePlugin dilate = MarvinPluginLoader.loadImagePlugin("org.marvinproject.image.morphological.dilation");
MarvinImagePlugin invert = MarvinPluginLoader.loadImagePlugin("org.marvinproject.image.color.invert");
// 2. Set plug-ins attributes
boolean[][] m = MarvinMath.getTrueMatrix(15,15);
erode.setAttribute("matrix", m);
dilate.setAttributes("matrix", m);
// 3. Load and process the image
MarvinImage image = MarvinImageIO.loadImage("./res/flowers.png");
invert.process(image.clone(), image);
MarvinImage binImage = MarvinColorModelConverter.rgbToBinary(image, 127);
MarvinImageIO.saveImage(binImage, "./res/flowers_bin.png");
erode.process(binImage.clone(), binImage);
dilate.process(binImage.clone(), binImage);
MarvinImageIO.saveImage(binImage, "./res/flowers_out.png");
}
public static void main(String[] args) {
new RemoveBackground();
}
}

Gabriel Archanjo
- 4,547
- 2
- 34
- 41