How do i smoothen the edges of a multicomponent image? - matlab

I have an image in which i would like to smoothen its edges. There was a bit of a challenge in getting a more accurate segmentation. I however got a solution by adapting the suggestion from: What can I do to enhance my image quality?.
The original images is here:
and segmented image as well
The code i used is as follows:
%# Read in image
Img = imread('image_name.png');
%# Apply filter
h = fspecial('average');
Img = imfilter(Img, h);
%# Segment image
Img = rgb2gray(Img);
thresh = multithresh(Img, 2);
Iseg = imquantize(Img, thresh);
figure, imshow(Iseg,[]), title('Segmented Image');
%# separate channels
blackPixels = (Iseg == 1);
grayPixels = (Iseg == 2);
whitePixels = (Iseg == 3);
%# grow white channel
whitePixels_dilated = imdilate(whitePixels, strel('disk', 4, 4));
%# Add all channels
Iseg(whitePixels | whitePixels_dilated) = 3;
figure, imshow(Iseg,[]);
My challenge right now is to smoothen the edges of the solid (whitePixels) or the edges of all objects. I have no idea how to do this. I have tried filtering but that only takes off the small spots.
Please any help, ideas, or suggestions or advice is greatly appreciated. Thank you.

I would suggest applying a rectangular filter multiple times. Here's an approach of how to do this:
I=imread('Orl1r.png');
I_gray=rgb2gray(I);
I_filtered=I_gray; % initialize the filtered image
for ii=1:10
I_filtered=imfilter(I_filtered,1/25*ones(5)); % apply rectangular-filter multiple times
end
figure
subplot(1,2,1)
imshow(I,[0 255]);
subplot(1,2,2);
imshow(I_filtered,[0 255])
Here's what the filtered image would look like:
Hope this helps.
EDIT: Instead of the rectangular filter you could also use a Gaussian one. But the general idea of applying multiple times persists. You can create a Gaussian filter for exapmle using f=fspecial('gaussian',5,6) which creates a 5x5 filtermask with sigma=6.

Related

MATLAB: Segment Image

New to MATLAB and image processing.I need to know how to segment an image into foreground and background, then generate a binary image as output.
I need this as an output:
I have already tried to accomplish this with online tutorials and this is what i managed to get:
Its a good start but not exactly what i need.
My Code:
I = imread('AssignmentInput.jpg');
figure;
imshow(I);
title('Step-1: Load input image');
img_filtered = I;
for c = 1 : 3
img_filtered(:, :, c) = medfilt2(I(:, :, c), [3, 3]);
end
figure;
imshow(img_filtered);
title('Step-3:Noise Removal');
H = fspecial('gaussian'); % Create the filter kernel.
img_filtered = imfilter(img_filtered,H); % Blur the image.
Mask = im2bw(img_filtered, 0.9); % Now we are generating the binary mask.
img_filtered([Mask, Mask, Mask]) = 0; % Now we have the image.
figure;
imshow(img_filtered);
title('Step-5:Segmented Image');
For a better noise removal process and cleaner separation between foreground and background, you can also add morphological operations like:
se = strel('square',2);
I = imclose(I,se);
You can try out different variations of 'strel' class also. The image below is after imclose operation with a square of 2 pixel

How to remove multifrequency noise from image using filter in matlab?

I have an image that has multi frequency noise, I used the code in this link :
Find proper notch filter to remove pattern from image
source image : orig_image
But my final image noise has not been removed.
As you know, I must remove the gradient in vertical direction. the frequency representation of image come in below:
fft of image
Have anyone idea for removal of this noise in matlab?
I apply sobel filter and median filter but not improved.
Note that my goal is remove of lines inside of object.
Regards.
You have two kinds of noise: irregular horizontal lines and salt and pepper. Getting rid of the lines is easy as long as the object doesn't cover the whole horizontal range (which it doesn't in your example).
I just sample a small vertical stripe on the left to only get the stripes and then subtract them from the whole image. Removing the salt and pepper noise is simple with a median filter.
Result:
Code:
% read the image
img = imread('http://i.stack.imgur.com/zBEFP.png');
img = double(img(:, :, 1)); % PNG is uint8 RGB
% take mean of columsn 100..200 and subtract from all columns
lines = mean(img(:, 100:200), 2);
img = img - repmat(lines, 1, size(img, 2));
% remove salt and pepper noise
img =medfilt2(img, [3,3], 'symmetric');
% display and save
imagesc(img); axis image; colormap(gray);
imwrite((img - min(img(:))) / (max(img(:)) - min(img(:))), 'car.png');
here is code I once used for an assignment I once had to do. It was a much simpler example than the one you have. There were only a total of 4 components in the frequency domain causing noise, so simply setting those 4 components to zero manually (hfreq) solved my problem. I dont know how well this will work in your case, perhaps writing an algorithm to find the appropriate hfreqs that stand out will help. Here was the original image I used :
This is the code I used :
% filtering out the noisy image
clc
clear all
close all
image = imread('freqnoisy.png');
image = double(image);
image = image/(max(max(image)));
imshow(image) % show original image
Fimage = fft2(image);
figure
imshow(((fftshift(abs(Fimage)))),[0 5000]) %shows all frequency peaks that stick out
hfreq = ones(256);
hfreq(193,193)=0;
hfreq(65,65) = 0;
hfreq(119,105) = 0;
hfreq(139,153)= 0;
%
Fimage_filtered = fftshift(Fimage).*hfreq;
figure
imshow(abs(Fimage_filtered),[0 5000]) % show freq domain without undesired freq
filtered_im = ifft2(ifftshift(Fimage_filtered));
figure
imshow(filtered_im)
this is what your output will look like :

Finding similar corners in matlab

I need to find similar corners in image (for example: 4 corners of a rectangle, same corners, just different orientation?).
I have this code:
% read the image into MATLAB and convert it to grayscale
I = imread('s2.jpg');
Igray = rgb2gray(I);
figure, imshow(I);
% We can see that the image is noisy. We will clean it up with a few
% morphological operations
Ibw = im2bw(Igray,graythresh(Igray));
se = strel('line',3,90);
cleanI = imdilate(~Ibw,se);
figure, imshow(cleanI);
% Perform a Hough Transform on the image
% The Hough Transform identifies lines in an image
[H,theta,rho] = hough(cleanI);
peaks = houghpeaks(H,10);
lines = houghlines(Ibw,theta,rho,peaks);
figure, imshow(cleanI)
% Highlight (by changing color) the lines found by MATLAB
hold on
After running this code I convert my starting image into a binary image with:
binary = im2bw(I);
after this I get a product from those 2 binary images and I think I get corners..
product = binary .* cleanI;
now I imfuse this picture with grayscale starting picture and get this:
I dont know what to do to get only those 4 corners!
Ok second try. Below a code that does not finally do the job but it might help.
Edge identifies the contours and with regionprops you get the characteristica of each identified element. As soon as you know what characteristics your desired object has you can filter it and plot it. I went through the Areas in shapedata.Area and the 6th largest was the one you were searching for. If you combine Area with some of the other charateristica you might get the one you want. As I said not ideal and final but perhaps a start ...
clear all
close all
source = imread('Mobile Phone.jpg');
im = rgb2gray(source);
bw = edge(im ,'canny',[],sqrt(2));
shapedata=regionprops (bwlabel(bw,8),'all');
%index = find([shapedata.Area]== max([shapedata.Area]));
index = 213;
data = shapedata(index).PixelList;
figure
imshow(im)
hold on
plot(data(:,1),data(:,2),'ro');

extracting leaf after watershed segmentation in matlab

after I applied watershed segmentation, I want to extract remained leaf from image,and only I want to get without background like image-2. Please can you help me. Thanks a lot. I attach below also my code.
I'm new at stackoverflow, therefore I'm not allowed to post images.I asked the same qustion in mathworks, you can check the images from there if you will.
Thanks a lot in advance.
http://www.mathworks.com/matlabcentral/answers/237106-extracting-leaf-from-background
image-1: after watershed segmentation(colored version):
image-2:image to be ;
my code:
% I -- intensity image
% Gmag -- gradient mag.
se = strel('disk', 30);
Ie = imerode(I, se);
Iobr = imreconstruct(Ie, I);
figure
imshow(Iobr), title('Opening-by-reconstruction (Iobr)')
Iobrd = imdilate(Iobr, se);
Iobrcbr = imreconstruct(imcomplement(Iobrd), imcomplement(Iobr));
Iobrcbr = imcomplement(Iobrcbr);
figure
imshow(Iobrcbr), title('Opening-closing by reconstruction (Iobrcbr)')
fgm = imregionalmax(Iobrcbr);
figure
imshow(fgm), title('Regional maxima of opening-closing by reconstruction (fgm)')
% modify area
I2 = I;
I2(fgm) = 255;
figure
imshow(I2), title('Regional maxima superimposed on original image (I2)')
se2 = strel(ones(10,10));
fgm2 = imclose(fgm, se2);
fgm3 = imerode(fgm2, se2);
fgm4 = bwareaopen(fgm3, 100);
I3 = I;
I3(fgm4) = 255;
figure
imshow(I3)
title('Modified regional maxima superimposed on original image (fgm4)')
% background markers
bw = im2bw(Iobrcbr, graythresh(Iobrcbr));
figure
imshow(bw), title('Thresholded opening-closing by reconstruction (bw)')
D = bwdist(bw);
DL = watershed(D);
bgm = DL == 0;
figure
imshow(bgm), title('Watershed ridge lines (bgm)')
gradmag2 = imimposemin(Gmag, bgm | fgm4);
L = watershed(gradmag2);
I4 = I;
I4(imdilate(L == 0, ones(3, 3)) | bgm | fgm4) = 255;
figure
imshow(I4)
title('Markers and object boundaries superimposed on original image (I4)')
Lrgb = label2rgb(L, 'jet', 'w', 'shuffle');
figure
imshow(Lrgb)
title('Colored watershed label matrix (Lrgb)')
figure
imshow(I)
hold on
himage = imshow(Lrgb);
himage.AlphaData = 0.3;
title('Lrgb superimposed transparently on original image')
props = regionprops(L);
[~,ind] = max([props.Area]);
imshow(L == ind);
It's not possible to extract the leaf according to the segmented image, because the yellow component cuts the leaf in different parts.
Moreover, according to the source code, I understand that you use a basic watershed that produces an over segmentation. Use a watershed constrained, also known as watershed with markers.
Find a way to share the original image and the image after processing.
I confirm that you certainly have an issue with the watershed you use. I ran your code on my own library, and I used: one inner marker (biggest component, consequently the leaf on the corner is discarded), one outer (dilation of the inner), the gradient image.
And here is my result: www.thibault.biz/StackOverflow/ResultLeaf.png. So only one component, because I use only one inner marker. It's not perfect, but already closer and easier to post-process.

how to remove noise from a special area in Matlab

I have a an image of size 180x220 containing some noise in the region for example (145:180,1:65).
My question is how to remove the noise in this region without affecting the other parts of the image using Matlab.
Thank you very much.
Edit: I want to remove the noise in the regions (1:146,1:25) and (1:15,25,174) from the following image:
In general, this would go something like
% filter image in-place
img(145:180, 1:65) = medfilt2(img(145:180, 1:65));
Note that most filters require some context of the region of interest to do a proper interpolation/averaging/etc., so you might want to take this approach:
% Note: increase ROI by 10 on each side
offset = 10;
img_tmp = img(145-offset : 180+offset, 1 : 65+offset);
% apply filter
img_tmp = medfilt2(img_tmp, [additional parameters]);
% put filtered image back in its proper place
img(145:180, 1:65) = img_tmp(offset:end-offset+1, 1:end-offset+1);
img = double(imread('img.jpg'));
h = fspecial('gaussian', hsize, sigma); % decide how to filter the image
img_filt = imfilter(img, h, 'replicate');
now, use the filtered image only in the noise region
img(145:180,1:65,:) = img_filt(145:180,1:65,:);
Edit: After you posted the image I guess you want simply replace the noised region by the vanilla color?
If so, then do the following (assuming gray image):
med_pixel = median(img(:)); % detect the dominant color
img(1:146,1:25) = med_pixel;
img(1:15,25,174) = med_pixel;
... and so on