How to fill a large hole?

6 ビュー (過去 30 日間)
John
John 2025 年 1 月 13 日
編集済み: DGM 2025 年 1 月 13 日
The imfill function doesn't fill the large hole. How can I fill it?
Or, more generally:
How can I separate the image from the background?
Using a very large 'disk' might work to fill the hole, but it would also make the subject too large.
Any suggestions?
Thank you!
I = imread("sample_image.png");
BW = imbinarize(I);
se = strel('disk',40);
closeBW = imclose(BW,se);
BW2 = imfill(closeBW,'holes');
figure
imshowpair(I,BW2,'montage')

採用された回答

DGM
DGM 2025 年 1 月 13 日
編集済み: DGM 2025 年 1 月 13 日
I don't have the original image, but I'm going to assume that your image is RGB. Use im2gray() to make sure that the incoming image is single-channel; otherwise, imbinarize() will treat it as a volumetric image, which causes problems further along the line with imfill().
  2 件のコメント
John
John 2025 年 1 月 13 日

It’s a gray image.

DGM
DGM 2025 年 1 月 13 日
編集済み: DGM 2025 年 1 月 13 日
The given image is RGB -- but only because it's a screenshot. I can only guess the problem because I have to guess at the size and depth of the original.
If the image is RGB, it will be treated as a volumetric image. When imfill() is given the resultant MxNx3 logical image, it will also treat it as a volumetric image. In this assumption, the holes are not filled because they are not closed. They are fully-connected to the image boundary (at the top and bottom pages of the volume).
inpict = imread('image.jpg'); % this is RGB (MxNx3)
BW = imbinarize(inpict);
se = strel('disk',40);
closeBW = imclose(BW,se);
BW2 = imfill(closeBW,'holes');
imshowpair(inpict,BW2,'montage','scaling','none')
If the image is a single channel image, the binary image is as well. In this case, the holes are closed and isolated from the image boundary.
inpict = im2gray(inpict); % now it is I (MxNx1)
BW = imbinarize(inpict);
se = strel('disk',40);
closeBW = imclose(BW,se);
BW2 = imfill(closeBW,'holes');
imshowpair(inpict,BW2,'montage','scaling','none')
If imfill() isn't filling the area, then either:
  • the image is not single-channel
  • the hole is not fully enclosed
  • there is some other function named imfill() which is shadowing IPT imfill()
  • something else
There's one other clue I should point out here. Note that I used different arguments in my calls to imshowpair(). There's a reason for that. Let's see what happens if I pass a single-channel image (the RHS) to imshowpair() with the original usage:
imshowpair(inpict,BW2,'montage')
Notice that the contrast is much higher than in any of the previous examples. That's because by default, imshowpair() will normalize grayscale images for display, which effectively stretches the contrast. This display normalization is not applied to RGB images. I used the extra scaling arguments in the two examples above so that they appeared the same.
Given that the image in the screenshot is clearly not normalized, I have to conclude that either your image is not a single-channel image, or the screenshot does not correspond to the specific usage of imshowpair() that is shown.

サインインしてコメントする。

その他の回答 (1 件)

Walter Roberson
Walter Roberson 2025 年 1 月 13 日
編集済み: Walter Roberson 2025 年 1 月 13 日
The provided JPEG image is RGB, not gray.
The provided JPEG image has a white border around it.
I = imread('https://www.mathworks.com/matlabcentral/answers/uploaded_files/1823171/image.jpeg');
I = rgb2gray(I);
I = imclearborder(I);
BW = imbinarize(I);
se = strel('disk',40);
closeBW = imclose(BW,se);
BW2 = imfill(closeBW,'holes');
imshow(BW2)

カテゴリ

Help Center および File ExchangeNeuroimaging についてさらに検索

製品


リリース

R2024a

Community Treasure Hunt

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

Start Hunting!

Translated by