How to remove open edge segments?

3 views (last 30 days)
MD FARHAN
MD FARHAN on 19 Mar 2021
Edited: darova on 22 Mar 2021
I want to remove all the black lines/pixels which do not form a closed boundary.
The result should look like this.
I have done component labelling but dont know how to proceed further.
I have thought of identying the closed boundary of all the components first then assigning a single color (white in my case) to all the components. Can anyone suggest how to do it?

Answers (2)

DGM
DGM on 22 Mar 2021
Edited: DGM on 22 Mar 2021
Technical image processing isn't my big thing, but I'll try.
% reduce to a binary image
% i'm assuming you have a better image copy
% or have otherwise established a good way of doing this already
% jpeg compression really makes a mess of fine edges
inpict=rgb2gray(imread('edges.jpg'));
tpict=medfilt2(inpict,[3 3])>225;
% get rid of unconnected edges in the hopes that this
% reduces the amount of work that needs to be done later
majorboundary=~bwareafilt(~tpict,1,'largest');
% skeletonize remaining edges
reduced=~bwmorph(~majorboundary,'thin',Inf);
% remove endpoints until the image stops changing
thisdelta=1;
while thisdelta>0
lastcopy=reduced;
reduced=reduced | bwmorph(~reduced,'endpoints');
err=abs(lastcopy-reduced);
thisdelta=sum(err(:));
end
% view result
imshow(reduced)
Yields this:
One problem with this approach is that it will also remove any closed edges which are not connected to the main group of edges. Providing that the prefiltering/thresholding step can extract a clear representation of the edges, then skipping the bwareafilt() step should avoid removing unconnected closed edges. In my hasty filtering/thresholding example, a lot of details did not survive to begin with. As I mentioned, I'm assuming you either have a better copy of the image or have already managed to reduce it to a binary image of sufficient accuracy. Omitting the bwareafilt() step gives us this:
Also, even if the filtering/thresholding is good and isolated loops are preserved, this method does not remove branches that terminate in a closed loop (see lower right).
Furthermore, note the behavior near the image boundary. If the image boundary is to be considered an edge, then perhaps adding 1px of temporary padding to the image will help preserve edges which meet the image boundary.

darova
darova on 22 Mar 2021
Edited: darova on 22 Mar 2021
You can use bwlabel to separately inspect each region. Use imclose to filter
Example (not tested)
I = imread('image.png');
B = im2bw(I); % binarize
[L,n] = bwlabel(B); % separate each region
A = B*0;
for i = 1:n
B1 = L==i; % choose region
B2 = imclose(B1,ones(3));
A = A | B2; % merge regions together
end
imshow(A)

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!