matlab encircle white areas in a black image - matlab

I have a grayscale image, which I convert to black and white image, and do some processing on it. After the processing, I have a black and white image which has groups of white pixels in a black image. So I want to place circles around the areas which are white in resultant image, but in original image.
I have thought of many approaches but am still unable to start with any approach.
Please help.

You can use regionprops to get some statistics about connected white regions in a binary image, and estimate a region radius from that.
im = imread('moon.jpg');
bw = im2bw(im);
stats = regionprops(bw);
imshow(im);
hold on;
t = 0:.01:2*pi;
for i = 1:numel(stats)
bb = stats(i).BoundingBox;
radius = mean([bb(3),bb(4)])/2;
plot(bb(1)+radius+radius*sin(t), bb(2)+radius+radius*cos(t));
end
Gives:

Related

how to separate the white regions bounded by black in a binary image

I am working with lung cancer detection in MATLAB. I want to segment the binary image of lung CT scan to fetch the region of interest.
In the picture you can see a white region inside the black region.The black objects signifies the lung and the white region inside black object signifies cancer effected portion of lung. I want to obtain the white region from the image. I want to get the output as only that white region in black background nothing else. How can I achieve this?
How about something like this:
% Read in image and convert to BW
BW = im2bw(imread('http://i.stack.imgur.com/pxpOz.jpg'));
% Invert so that the lung appears white white
BW = ~BW;
% Create a structuring element. Tune the '2' depending on the size of the gap
se = strel('disk',2);
% Perform mophological closing
closeBW = imclose(BW,se);
% Fill the holes
lungBW = imfill(closeBW,'holes');
% subtract the lung image from the closed image
cancerBW = (lungBW - closeBW);
% Display the results
figure; imshow(cancerBW);
Click here for the output
You have not given code, so I am also answering without code.
You could
use morpholocical closing operation to get rid of the open channel which connects the white region to the surrounding
Then look for white holes in each black region (e.g. by doing a blob analysis /threshold operation only on the (masked) region which is black)
Alternatively, you could
look for convexity defects of contours such as described here (This is a python version, but similar functions should be around in matlab)

contour line edge detection in MATLAB [duplicate]

This question already exists:
contour Detection in MATLAB with GUI
Closed 7 years ago.
I have a project to detect the contour lines in image , but when I run my code with the canny edge detection algorithm , one line in the image transforms to two lines, because of two times the change in grey values of the line before and after that .
i= imread('path');
imgG= rgb2gray(i);
PSF = fspecial('gaussian',7,7);
Blurred = imfilter(imgG,PSF,'symmetric','conv');
figure ,imshow(Blurred)
edgeimg = edge(Blurred , 'canny');
figure ,imshow(edgeimg)
I have no idea to solve this, please help me.
The best answer depends on what you want to do with the edges after detecting them, but let's assume you just want to generate an image where the lines are pure black and everything else is pure white...
The simplest approach is to threshold the image so that lighter grey pixels become white and darker grey pixels become black. You can also erode the image to try and reduce the thickness of lines -- although you'll find that this will get rid of the fine contours in your sample image.
Here is the code to do this (assumes you have the image G4.jpg in your working folder).
% load image and convert to double (0 to 1) as well as flip black and white
imG4 = imread('G4.jpg');
imG4_gs = 1 - mean(double(imG4)/255,3);
figure
image(64*(1 - imG4_gs))
colormap('gray');
axis equal
% image grayscale threshold
img_thr = 0.25;
% apply threshold to image
imG4_thr = imG4_gs >= img_thr;
figure
image(64*(1 - imG4_thr))
colormap('gray');
axis equal
% erode image (try "help imerode" in the MATLAB console)
imG4_ero = imerode(imG4_thr,strel('disk',1));
figure
image(64*(1 - imG4_ero))
colormap('gray');
axis equal;

Boundary around an object

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?
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:
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));
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
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:
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:
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:
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:
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!
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.

LED Screen recognition in image using MATLAB

I'm trying to detect the screen border from the image (In need the 4 corners).
This is the Image:
I used HOUGH transform to detect lines and intersection points (the black circles) and this is the result:
Now I need to find the 4 corners or the 4 lines.. everything that will help me to crop the image, What can I do?
Maybe use the screen aspect ratio? but how?
I'm using Matlab.
Thanks.
A naive first approach that would do the trick if and only if you have same image conditions (background and laptop).
Convert your image to HSV (examine that in HSV the image inside the
screen is the only portion of the image with high Saturation, Value
values)
Create a mask by hard thresholding the Saturation and Value channels
Dilate the mask to connect disconnected regions
Compute the convex hull to get the mask boundaries
See a quick result:
Here is the same mask with the original image portion that makes it through the mask:
Here is the code to do so:
img = imread( 'imagename.jpg'); % change the image name
hsv = rgb2hsv( img);
mask = hsv(:,:,2)>0.25 & hsv(:,:,3)>0.5;
strel_size = round(0.025*max(size(mask)));
dilated_mask=imdilate(mask,strel('square',strel_size));
s=regionprops(dilated_mask,'BoundingBox','ConvexHull');
% here Bounding box produces a box with the minimum-maximum white pixel positions but the image is not actually rectangular due to perspective...
imshow(uint8(img.*repmat(dilated_mask,[1 1 3])));
line(s.ConvexHull(:,1),s.ConvexHull(:,2),'Color','red','LineWidth',3);
You may, of course, apply some more sophisticated processing to be a lot more accurate and to correct the convex hull to be just a rectangular shape with perspective, but this is just a 5 minutes attempt just to showcase the approach...

Filling some region with colour, and the rest of the image as black

I have drawn some polygon on an image after using imshow and hold on, and filled it with white as follows:
fill(x(k),y(k),[1 1 1])
How can I make the rest of the image black while keeping the polygon white? In other words, how can I make a binary image, where the polygon is white, and the rest of the image is black? Provided that the polygon is a bit complex.
Thanks.
Use roipoly:
BW = roipoly( I, x(k), y(k) );
Where I is your input image (you only need it to get the desired output size of the binary maxk BW). y and x are the corners of your polygon.