Remove scratches from binary image

조회 수: 11 (최근 30일)
Adrian Reuther
Adrian Reuther 2020년 2월 16일
답변: Deep 2024년 10월 17일
Hi everybody,
right now I am struggling with a problem. I got a binary image which contains unwanted scratches. In the uploaded image you can see which objects need to be removed (red rectangular). The following code already works, but it also removes everything else inside the rectangular. Since I want to keep the other objects, the code needs to be modified. My question is: How can the code be modified, to only erase the scratches and not the other objects?
Subtract=Vergleich-Referenz;
binary=imbinarize(Subtract,0.14);
se=strel('disk',4);
close=imclose(binary,se);
close=imfill(close,'holes');
stats=regionprops('table',close,'BoundingBox','MajorAxisLength','MinorAxisLength','SubarrayIdx','Area','Perimeter','Centroid');
stats.LenWdRatio = stats.MajorAxisLength ./ stats.MinorAxisLength;
thresh = 3;
stats.isGreater = stats.LenWdRatio < thresh;
objRemoveIdx=find(~stats.isGreater);
for i = find(~stats.isGreater).'
close(stats.SubarrayIdx{i,1},stats.SubarrayIdx{i,2}) = false;
end
se=strel('disk',3);
open=imopen(close,se);
filter=bwareafilt(open,[10 1000]);
stats.circularity=4*pi*stats.Area./stats.Perimeter.^2;
thresh=0.5;
stats.isBigger = stats.circularity >thresh;
for i = find(~stats.isBigger).'
filter(stats.SubarrayIdx{i,1},stats.SubarrayIdx{i,2}) = false;
end
invert=imcomplement(filter);
I would be very thankful for an answer.
Greetings!

답변 (1개)

Deep
Deep 2024년 10월 17일
Hi Adrian,
To remove the unwanted scratches from a binary image while preserving other objects, we need to focus on the contours of the scratches. The original approach removed entire regions within the bounding boxes, which led to the undesired removal of other objects. Instead, you can use “bwboundaries” function (https://www.mathworks.com/help/images/ref/bwboundaries.html) to identify these contours and create a contour mask. Finally, you can subtract this contour mask from the binary image to remove only the unwanted contours. Here's a snippet that illustrates this approach:
% Find boundaries using bwboundaries
[B, L] = bwboundaries(binary, 'noholes');
% Create a mask for the contours of the scratches
contourMask = false(size(binary));
% Process only the contours of the scratches
for i = find(~stats.isGreater).'
boundaries = B{i};
boundaryMask = poly2mask(boundaries(:,2), boundaries(:,1), size(binary, 1), size(binary, 2));
contourMask = contourMask | boundaryMask;
end
% Dilate the contour mask to remove thin edge artifacts
se = strel('disk', 1);
dilatedContourMask = imdilate(contourMask, se);
% Remove the contours from the original image
binary(dilatedContourMask) = false;
This should help give the desired output:
Note that I dilated the contour mask by 1 pixel using “strel” (https://www.mathworks.com/help/images/ref/strel.html) and “imdilate” (https://www.mathworks.com/help/images/ref/imdilate.html); this helps remove some undesired edge artifacts near the scratches in the filtered output.

태그

Community Treasure Hunt

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

Start Hunting!

Translated by