Image Morphing in Matlab - matlab

I want to use mathematical morphology function in MATLAB to find the boundary of can.png image. The input image is:
I want to get a boundary such as :
I tried to use different combination and parameter using strel, imerode, imdilate , But the result is not good enough (far from the expectation)
One of my trial code is:
a = imread ('can.png');
b = im2bw(a);
SE = strel('rectangle', [10 50 ]) ;
i2 = imdilate(b,SE);
figure(1); imshow(i2);
p = ones(4);
c = b - imerode(b,p);
figure(2); imshow(c);
The output is:
Can any body help me, how to create the expected image (black background with thin boundary for the can, please? Thank you very much.

Binarize on its morphological gradient, then do a dilation with an elementary SE, fill holes and finally obtain its border (trivial given the current image). This doesn't require any magical arbitrary threshold.

im = imread('can.png');
% turn image to BW
imb = (im < 220);
% fill the holes in the image
imf = imfill(imb, 'holes');
% find the edge
ed = edge(imf);
Resulting image:

Related

How to smoothen the edges from an image obtained from imagesc function

I have an RGB image obtained from saving the imagesc function as shown below. how to refine/smoothen the edges present in the image.
It consists of sharper edges, where I need to smoothen them. Im not able to find a solution for performing this for an RGB image. Instead of the staircase effect seen in the image I'd like to even out the edges. Please help thanks in advance.
maybe imresize will help you:
% here im just generating an image similar to yours
A = zeros(20);
for ii = -2:2
A = A + (ii + 3)*diag(ones(20-abs(ii),1),ii);
end
A([1:5 16:20],:) = 0;A(:,[1:5 16:20]) = 0;
subplot(121);
imagesc(A);
title('original')
% resizing image with bi-linear interpolation
B = imresize(A,100,'bilinear');
subplot(122);
imagesc(B);
title('resized')
EDIT
here I do resize + filtering + rounding:
% generates image
A = zeros(20);
for ii = -2:2
A = A + (ii + 3)*diag(ones(20-abs(ii),1),ii);
end
A([1:5 16:20],:) = 0;A(:,[1:5 16:20]) = 0;
subplot(121);
imagesc(A);
title('original')
% resizing
B = imresize(A,20,'nearest');
% filtering & rounding
C = ceil(imgaussfilt(B,8));
subplot(122);
imagesc(C);
title('resized')
solution
use imfilter and fspecial to perform a convolution of you image with gaussian.
I = imread('im.png');
H = fspecial('gaussian',5,5);
I2 = imfilter(I,H);
change 'blurlevel' parameter (which determines the gaussian kernel size) to make the image smoother or sharper.
result
If you are just looking for straighter edges, like an elevation map you can try contourf.
cmap = colormap();
[col,row] = meshgrid(1:size(img,2), 1:size(img,1));
v = linspace(min(img(:)),max(img(:)),size(cmap,1));
contourf(col,row,img,v,'edgecolor','none');
axis('ij');
This produces the following result using a test function that I generated.

Matlab : Remove skin part on segmentation

How to remove skin parts on segmentation ?
First, I made this first picture smaller, since the picture is somehow intimidating, I'll give the image at the end section.
I'm using RGB & ycbcr segmentation, but it seems the segmentation didn't work well.
clear all;
close all;
clc;
img=imread('acne.jpg');
%ycbcr segmentation
img_ycbcr=img; %image from the previous segmentation
ycbcr=rgb2ycbcr(img_ycbcr);
cb=ycbcr(:,:,2);
cr=ycbcr(:,:,3);
%Detect Skin
%[r,c,v] = find(cb>=77 & cb<=127 & cr>=133 & cr<=173);
[r c v] = find(cb<=77 | cb >=127 | cr<=133 | cr>=173);
numid = size(r,1);
%Mark Skin Pixels
for i=1:numid
img_ycbcr(r(i),c(i),:) = 0;
% bin(r(i),c(i)) = 1;
end
figure
title('ycbcr segmentation');
imshow(img_ycbcr);
%==============================================================
%rgb segmentation
img_rgb=img_ycbcr;
r=img_rgb(:,:,1);
g=img_rgb(:,:,2);
b=img_rgb(:,:,3);
[row col v]= find(b>0.79*g-67 & b<0.78*g+42 & b>0.836*g-14 & b<0.836*g+44 ); %non skin pixels
numid=size(row,1);
for i=1:numid
img_rgb(row(i),col(i),:)=0;
end
figure
imshow(img_rgb);
Here my sample :
I agree with Adriaan. Don't do it with just colour, use additional information such as the shape and the edges.
The last two colorplanes seem to have the most contrast, so let's use one of them:
Nipple = imread('N8y6Q.jpg')
Nipple = imadjust(Nipple(:,:,2));
imshow(Nipple)
[centers, radii] = imfindcircles(Nipple, [30,60]);
hold on
imshow(Nipple);
viscircles(centers, radii);
The circular Hough transform is a robust way to find circular objects if you know the approximate radius range and are satisfied with the approx. location and size of the object.
If not you can try other classical methods, e.g. (Canny) edge detection, using the Hough center point as a marker -> region growing, fitting a snake etc. etc.

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');

how to embed a watermark inside roi in matlab

the region of interest in the image are calculated. Now how to embed the watermark into the roi..i ve put the code for embedding it in the whole image in lsb. How can it modified for roi alone?
clear all;
file_name='pout.tif';
cover_object=imread(file_name);
file_name='cameraman.tif';
message=imread(file_name);
message=double(message);
message=round(message./256);
message=uint8(message);
Mc=size(cover_object,1);
Nc=size(cover_object,2);
Mm=size(message,1);
Nm=size(message,2);
for ii = 1:Mc
for jj = 1:Nc
watermark(ii,jj)=message(mod(ii,Mm)+1,mod(jj,Nm)+1);
end
end
watermarked_image=cover_object;
for ii = 1:Mc
for jj = 1:Nc
watermarked_image(ii,jj)=bitset(watermarked_image(ii,jj),1,watermark(ii,jj));
end
end
imwrite(watermarked_image,'watermarkedimage','bmp');
figure(1)
imshow(watermarked_image,[])
title('Watermarked Image')
If your roi is rectangular, just loop over the appropriate subsection of the image rather than the whole thing.
If not, and you can define the watermarking as some function:
imgout = watermark(img1, img2);
Then you can use roifilt2 to apply that function just in your roi.
In this simple example,mask is a BW matrix where 1 indicates part of our roi (a mask can be created several different ways including using some of the interactive roi functions, see bottom section). img1 and img2 have already been loaded:
f = #(x) watermark(x,img2); % our very basic function
imgout = roifilt2(img1,mask,f);
Complications may arise if your img2 is smaller than img1 (or if you want to resize it to just cover the roi area). In this case, do everything on a subsection of img1/mask and then assemble the final image:
img1_s = img1(a:b,c:d); % these return the same size as img2
mask_s = mask(a:b,c:d);
imgout_s = roifilt2(img1_s,mask1_s,f);
imgout = img1;
imgout(a:b,c:d) = imgout_s;
A mask can be created several ways, some using the interactive roi functions, some not. A lot depends on how you have your roi in the first place - do you have a centre/radius, or do you want to hand-pick the location interactively, etc. Here are a few examples making use of the Image Processing Tool Box:
Interactive ROI function and createMask.
This will work for any of the interactive roi functions (imellipse, imfreehand, etc). You can interactively adjust the mask between the second and third steps. Do not close the image window before calling createMask.
h = imshow(img); %display image
e = imellipse(gca,[50 50 100 100]); % select roi
mask = createMask(e,h); % return mask
List of x/y points and poly2mask
If you have a list of points defining the outer edge of your roi, a quick non-interactive way of producing a mask is to use poly2mask. The third and fourth values define the total size of the mask returned.
mask = poly2mask(x,y,size(img,1),size(img,2));
Using morphological operators
strel defines a structuring element, and imdilate performs a dilation using that structuring element. Given an image which contains a single point, what that does is replace the point with the structuring element - in this case disk which will produce a circle (or as close as you can get using pixels). Other shapes (e.g. diamond) can be used with strel
mask = zeros(size(img));
mask(a,b) = 1; % a,b is the centre point of the circle
se = strel(disk,r,0); %r is the radius of the circle
mask = imdilate(mask,se);

How can I implement a fisheye lens effect (barrel transformation) in MATLAB?

How can one implement the fisheye lens effect illustrated in that image:
One can use Google's logo for a try:
BTW, what's the term for it?
I believe this is typically referred to as either a "fisheye lens" effect or a "barrel transformation". Here are two links to demos that I found:
Sample code for how you can apply fisheye distortions to images using the 'custom' option for the function maketform from the Image Processing Toolbox.
An image processing demo which performs a barrel transformation using the function tformarray.
Example
In this example, I started with the function radial.m from the first link above and modified the way it relates points between the input and output spaces to create a nice circular image. The new function fisheye_inverse is given below, and it should be placed in a folder on your MATLAB path so you can use it later in this example:
function U = fisheye_inverse(X, T)
imageSize = T.tdata(1:2);
exponent = T.tdata(3);
origin = (imageSize+1)./2;
scale = imageSize./2;
x = (X(:, 1)-origin(1))/scale(1);
y = (X(:, 2)-origin(2))/scale(2);
R = sqrt(x.^2+y.^2);
theta = atan2(y, x);
cornerScale = min(abs(1./sin(theta)), abs(1./cos(theta)));
cornerScale(R < 1) = 1;
R = cornerScale.*R.^exponent;
x = scale(1).*R.*cos(theta)+origin(1);
y = scale(2).*R.*sin(theta)+origin(2);
U = [x y];
end
The fisheye distortion looks best when applied to square images, so you will want to make your images square by either cropping them or padding them with some color. Since the transformation of the image will not look right for indexed images, you will also want to convert any indexed images to RGB images using ind2rgb. Grayscale or binary images will also work fine. Here's how to do this for your sample Google logo:
[X, map] = imread('logo1w.png'); % Read the indexed image
rgbImage = ind2rgb(X, map); % Convert to an RGB image
[r, c, d] = size(rgbImage); % Get the image dimensions
nPad = (c-r)/2; % The number of padding rows
rgbImage = cat(1, ones(nPad, c, 3), rgbImage, ones(nPad, c, 3)); % Pad with white
Now we can create the transform with maketform and apply it with imtransform (or imwarp as recommended in newer versions):
options = [c c 3]; % An array containing the columns, rows, and exponent
tf = maketform('custom', 2, 2, [], ... % Make the transformation structure
#fisheye_inverse, options);
newImage = imtransform(rgbImage, tf); % Transform the image
imshow(newImage); % Display the image
And here's the image you should see:
You can adjust the degree of distortion by changing the third value in the options array, which is the exponential power used in the radial deformation of the image points.
I think you are referring to the fisheye lens effect. Here is some code for imitating fisheye in matlab.
Just for the record:
This effect is a type of radial distortion called "barrel distortion".
For more information please see:
http: //en.wikipedia.org/wiki/Distortion_(optics)
Here is a different method to apply an effect similar to barrel distortion using texture mapping (adapted from MATLAB Documentation):
[I,map] = imread('logo.gif');
[h,w] = size(I);
sphere;
hS = findobj('Type','surface');
hemisphere = [ones(h,w),I,ones(h,w)];
set(hS,'CData',flipud(hemisphere),...
'FaceColor','texturemap',...
'EdgeColor','none')
colormap(map)
colordef black
axis equal
grid off
set(gca,'xtick',[],'ztick',[],'ytick',[],'box','on')
view([90 0])
This will give you the circular frame you are looking for but the aliasing artifacts might be too much to deal with.