Question

I want to make a boundary around an object and the object is within a grayscale image.

The approach that I want to perform is to subtract the region inside the boundary from the background.

This was the code I used:

s=imread('C:\Users\Deepinder\Desktop\dd.jpg');
t=im2bw(s);
se=strel('disk',2);
f1=imerode(t,se);
CC=f1-t;
imshow(CC)

However, I am getting a completely black image as a result. What am I doing wrong?

Was it helpful?

Solution 2

I would recommend to convert your image to HSV space with rgb2hsv function. Then you can use the first hue layer to make a mask.

im = imread(filename);
im2 = rgb2hsv(im);
mask = im2(:,:,1)>0.4 & im2(:,:,1)<0.6;
im3 = im;
im3(repmat(mask,[1 1 3])) = 255;
imshow(im3)

You can play more with this mask to fill a few gaps. I don't have the toolbox to test it throughly.

OTHER TIPS

I've come up with one solution, but I don't believe it is as accurate as you want, but it's something to start off with.

The image you are dealing with is actually quite complicated. This is the image that you have shown me:

enter image description here

What you would like to do is extract only the pixels that concern the face while making the background pixels black.

What we originally wanted to do was convert the image to black and white, then do an erosion and subtract this result with the original. This would work ONLY if the object had an overall brighter intensity than the background.

If you tried to do a straight up im2bw(), this would convert the image to grayscale first for colour images, then assume a threshold of 128. Anything larger than 128 would be white, while anything smaller is 0. This is the image that we would get followed by the accompanied code:

im = imread('dd.jpg');
imshow(im2bw(im));

enter image description here

As you can see, the background is also classified as white, and so our first approach won't work. What I did was decompose the image into separate channels (red, green and blue). This is what I get and here's the code to show it:

titles = {'Red', 'Green', 'Blue'};
for i = 1 : 3
   subplot(1,3,i);
   imshow(im(:,:,i));
   title(titles{i});
end

enter image description here

If you take a look at the red and green channels, the red channel is very noisy and so we'll leave that alone. The green channel has the background being very similar to the face, and so we'll leave that one too. The best one we can use is the blue channel as there is a relatively good separation between the face intensity profile and the background.

By using impixelinfo and moving around the blue channel image, I saw that intensity profiles of the face varied roughly between 120 to 200. As such, let's create a binary mask that does such:

im = imread('dd.jpg');
faceGray = im(:,:,3);
faceBW = faceGray > 120 & faceGray < 200;

This is the output I get:

enter image description here

We're almost there. I want to get rid of the outline of the hair. What I did was an opening filter with a disk structuring element of radius 3. This should thin out any small objects while keeping the bigger predominant objects.

se = strel('disk', 2);
faceOpened = imopen(faceBW, se);

This is what I get:

enter image description here

Now let's go ahead and fill in the holes. imfill won't work because it only fills in regions that are closed. As such, I'm going to cheat a bit and do a closing filter with a larger size disk. I chose a radius of 30 this time.

se2 = strel('disk', 30);
faceClosed = imclose(faceOpened, se2);

This is what I get:

enter image description here

Now the final step is to use this mask and mask out all of the background pixels:

mask = repmat(faceClosed, [1 1 3]);
out = uint8(zeros(size(im)));
out(mask) = im(mask);

... and this is what I get:

enter image description here

This is by no means perfect, but it gives you something to work with. Also, the intensity profile around the neck is very similar to the face and so doing it my way can't avoid extracting the neck. What I would suggest you do is crop out the image so that you mostly see the face, then try and do some morphology or even edge detection to help you out in a similar fashion to what I did. Hope this helps!

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top