Message Boards Message Boards

Removal of Complex Background and Separation of overlapping objects

Posted 8 years ago

Hello, My goal is to capture individual trees in the image attached (Original_Image) for both area calculation and counting. But, a problem is my functions do not separate overlapping trees so capture a group or cluster of trees (please see Image2). This is not good when counting the trees. I tried to use "WatershedComponents", which did not work either. I wonder if there are Wolfram functionalities that separate brownish background colour from greenish and bluish objects and also separate and capture overlapping objects individually. I really appreciate some inputs. Thank you very much!

These are my codes: `

greenQ[p:{r_,g_,b_}]:=With[{mean=Mean[p]},If[g>1.03 mean,1,0]]
mask=CommonestFilter[DeleteSmallComponents[Erosion[Dilation[ImageApply[greenQ, img], 1], 1], 150],3]
HighlightImage[img, EdgeDetect[mask], "HighlightColor" -> Yellow,  Method -> {"Boundary", 2}]

Original_Image Image2

POSTED BY: Eiji Matsuzaki
4 Replies
Posted 8 years ago

Dear Marco,

thank you very much for your heartening words! Although I do not regard the above as a very robust solution. Maybe somebody is coming up really with a clever idea ...

Best greetings from Germany -- Henrik

POSTED BY: Eiji Matsuzaki

Hi Eiji,

counting those trees appears not to be an easy task - even if one tries it by hand. So I guess an approximation is the best one can expect. Here is what I tried:

  • I separated the trees by its color - as before;
  • then I applied a SkeletonTransform, which I blured;
  • finally WatershedComponents seems to do the trick.

My result looks like:

enter image description here

I think one can see here at least a not unreasonable separation of single trees. My code:

ClearAll["Global`*"]
img = "your original image";
greenQ[p : {r_, g_, b_}] := With[{mean = Mean[p]}, If[g > 1.05 mean, 1, 0]]
mask = Dilation[Erosion[ImageApply[greenQ, img], 6], 4];
maskData = ImageData[mask];
img0 = ImageMultiply[mask, img]
img1 = Dilation[ImageAdjust@SkeletonTransform[mask], 1]
img2 = Blur[img1, 30] // ImageAdjust
wscData = WatershedComponents@ColorNegate[img2];
colorTrees = ImageMultiply[Colorize[wscData], mask]
Manipulate[Blend[{img, colorTrees}, p], {p, 0, 1}]

What is left for you to do (in case you find this meaningful at all) is to count occurrend colors (except black) down to some minimal patch size. Maybe this might be an approach.

Regards -- Henrik

POSTED BY: Henrik Schachner

Dear Henrik,

very (!) impressive indeed. I always enjoy your posts.

Cheers,

Marco

POSTED BY: Marco Thiel

Dear Marco,

thank you very much for your heartening words! Although I do not regard the above as a very robust solution. Maybe somebody is coming up really with a clever idea ...

Best greetings from Germany -- Henrik

POSTED BY: Henrik Schachner
Reply to this discussion
Community posts can be styled and formatted using the Markdown syntax.
Reply Preview
Attachments
Remove
or Discard

Group Abstract Group Abstract