Extracting external Boundary from Binary Image generated from noisy RGB
Show older comments
Hi there,
I am trying to extract the following outermost boundary from the following binary image. 

This image was generated from an rgb image using kmeans clustering. Unfortunately the background is highly noisy and the object depicted includes holes such that the background colour is visible within it. Due to the colour scheme of the object mainly in the greens to dark blues, it is near indistinguishable from the actual object other than through the border edge which is yellow. I therefore went into hsv to adapthisteq the hue at first then latter after seeing a couple of papers the saturation as well. This allows for the usage of kmeans clustering which correctly identifies the surrounding background, the internal structure and the border region into three seperate clusters.
Now after turning the clustered image into binary as seen above, I applied thed bwboundaries function which did not yield any real workable result. This most probably is due to the entire middle part of fuzzyness. Next I tried to bwareafilt, but as the background is inside as well this reduces at the thinner edges the boundary depending on size of pixel to keep. Lastly, I used the boundarymask funtion. This at least yields the below image. The external boundary has sometimes holes in it but seems to be traceable once a starting point is found. This can be done by using the corner points along the diagonals as to be orthogonal to the boundary.

As you may imagine this is only part of the image to illustrate the issue. The complete object is at best described as ellipitcal in shape though with the boundary being ridge as shown above. I have looked at ellipitcal growing and reducing algos as well but they just do not perform. Any hints as to what algorithm and implementations would be best suited for this issue are highly welcome. Thank you in advance for your time!
EDIT: As the issue seems to require the entire image, given that the complete image has properties which differ from the section shown. Although I hazard a guess it is the section in the centre of the image which causes the issue. Here is the complete image.

EDIT 2:
As it seems that the segmentation is inadequate, the original RGB image was added. Essentially, the feature extraction uses Kmeans Clustering to extract the clusters after some optimisation of colour in the hsv space. As my current computing setup only allows 15 GB, this is a trial resized image. Ideally if segmentation works this can be up scaled.

Accepted Answer
More Answers (2)
KALYAN ACHARJYA
on 16 Feb 2021
Edited: KALYAN ACHARJYA
on 16 Feb 2021
bwImage2=~bwareafilt(~bwImage,1); % Largest Blob
se=strel('line',10,10);
% Note one strel element, you may require to compensate the extra pixels
bw_roi=bwImage & ~imerode(bwImage2,se);
figure,imshow([bwImage,bw_roi]);

7 Comments
Maximilian Oremek
on 16 Feb 2021
KALYAN ACHARJYA
on 17 Feb 2021
"Does not work on the entire image though"
What does the whole image mean here? I have answered based on the image provided with the question, which works perfectly in my case.
Maximilian Oremek
on 17 Feb 2021
KALYAN ACHARJYA
on 17 Feb 2021
Hope now you can modify the code and get the more accurate result
se=strel('line',10,10);
bwImage1=imdilate(bwImage,se);
bwImage2=bwareafilt(~bwImage1,1); % Largest Blob
se=strel('line',15,15);
bw_roi=bwImage & imdilate(bwImage2,se);
figure,imshow([bwImage,bw_roi]);
Note one strel elements, you may require to compensate all those extra pixels

Maximilian Oremek
on 18 Feb 2021
KALYAN ACHARJYA
on 19 Feb 2021
As I have already shared, you may need some effort, but precise segmentation of the image is possible. You can get the exact boundary in the entire image by scanning first and last while pixels in individual columns (Issue: but yes, it will take a little longer).
Maximilian Oremek
on 19 Feb 2021
Image Analyst
on 17 Feb 2021
If you just want the top pixel of the quarter image, you can simply scan the image column by column looking for the first pixel in each column using find().
If you want the whole image, and you want to close that gap at the bottom, then you can close all gaps using bwconvhull()
mask = bwconvhull(mask);
Of course that will also fill in small indentations as well as the giant gap at the bottom. If you want to keep the exact shape and just fill in the giant gap then there are things you can do by combining the original image and the convex hull image in clever ways.
Or you might just look into using a better segmentation routine so that you start with a better binary image.
3 Comments
Maximilian Oremek
on 18 Feb 2021
Image Analyst
on 18 Feb 2021
Could you share your original RGB image?
Maximilian Oremek
on 19 Feb 2021
Categories
Find more on Deep Learning Toolbox in Help Center and File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!