3D plot of an image in Matlab - image

Based on the code given by Image Analyst in the answer to “3d plot of an image“ question (http://www.mathworks.com/matlabcentral/answers/48532-3d-plot-of-an-image) I have a follow-up question:
I simplified the code and I would like to know is it possible to apply on it the jet colormap according to the gray scale intensity (Z axis) and also to fit it to the image dimensions (x,y) (e.g, in this image example the dimensions are 628x600 and therefore max x=628 and max y=600).
Thanks.
Code:
I = imread('E:\Temp\Canadian_maple_leaf_2.jpg'); % http://en.wikipedia.org/wiki/File:Canadian_maple_leaf_2.jpg
I=rgb2gray(I);
I = imcomplement(I);
[rows columns numberOfColorBands] = size(I);
surf(double(I));

If I understand the question correctly, changing the colormap and turning the edge colours off is what you are looking for
surf(double(I),'EdgeColor','none');
colormap jet
If you want to tighten the boundaries of the plot, you can use
axis([0 columns 0 rows min(double(I(:))) max(double(I(:)))])

Related

need to plot a 2D graph of the gray image intensity in matlab

what I am trying is to compare two gray scale images by ploting their intensity into graph. The code is bellow is for single image.
img11 = imread('img.bmp');
[rows cols ColorChannels] = size(img11);
for i=1:cols
for j=1:rows
intensityValue = img11(j,i);
end
end
% below trying different plot method
plot(intensityValue);
plot(1:length(img11),img11);
plot(img11(:))
My expected result for two images is like below pictures: here
not like
this here
Based on your code you should be able to do the following.
img11 = imread('img1.bmp');
img22 = imread('img2.bmp');
figure;
imagesc(img11); % verify you image
figure;
plot(img11(:)); hold on;
plot(img22(:));
Using the command (:) will flatten a matrix into a single vector starting at the top left and going down in columns. If that is not the orientation that you want you try to rotate/transpose the image (or try using reshape(), but it might be confusing at the start). Additionally, if your image has large variations in the pixel intensity moving average filter can be useful.
Len = 128;
smooth_vector = filter(ones(Len,1)/Len,1,double(img11(:)));
figure; plot(smooth_vector);

Matlab detect rectangle from image [duplicate]

I need to know how to align an image in Matlab for further work.
for example I have the next license plate image and I want to recognize all
the digits.
my program works for straight images so, I need to align the image and then
preform the optical recognition system.
The method should be as much as universal that fits for all kinds of plates and in all kinds of angles.
EDIT: I tried to do this with Hough Transform but I didn't Succeed. anybody can help me do to this?
any help will be greatly appreciated.
The solution was first hinted at by #AruniRC in the comments, then implemented by #belisarius in Mathematica. The following is my interpretation in MATLAB.
The idea is basically the same: detect edges using Canny method, find prominent lines using Hough Transform, compute line angles, finally perform a Shearing Transform to align the image.
%# read and crop image
I = imread('http://i.stack.imgur.com/CJHaA.png');
I = I(:,1:end-3,:); %# remove small white band on the side
%# egde detection
BW = edge(rgb2gray(I), 'canny');
%# hough transform
[H T R] = hough(BW);
P = houghpeaks(H, 4, 'threshold',ceil(0.75*max(H(:))));
lines = houghlines(BW, T, R, P);
%# shearing transforma
slopes = vertcat(lines.point2) - vertcat(lines.point1);
slopes = slopes(:,2) ./ slopes(:,1);
TFORM = maketform('affine', [1 -slopes(1) 0 ; 0 1 0 ; 0 0 1]);
II = imtransform(I, TFORM);
Now lets see the results
%# show edges
figure, imshow(BW)
%# show accumlation matrix and peaks
figure, imshow(imadjust(mat2gray(H)), [], 'XData',T, 'YData',R, 'InitialMagnification','fit')
xlabel('\theta (degrees)'), ylabel('\rho'), colormap(hot), colorbar
hold on, plot(T(P(:,2)), R(P(:,1)), 'gs', 'LineWidth',2), hold off
axis on, axis normal
%# show image with lines overlayed, and the aligned/rotated image
figure
subplot(121), imshow(I), hold on
for k = 1:length(lines)
xy = [lines(k).point1; lines(k).point2];
plot(xy(:,1), xy(:,2), 'g.-', 'LineWidth',2);
end, hold off
subplot(122), imshow(II)
In Mathematica, using Edge Detection and Hough Transform:
If you are using some kind of machine learning toolbox for text recognition, try to learn from ALL plates - not only aligned ones. Recognition results should be equally well if you transform the plate or dont, since by transforming, no new informations according to the true number will enhance the image.
If all the images have a dark background like that one, you could binarize the image, fit lines to the top or bottom of the bright area and calculate an affine projection matrix from the line gradient.

Make a representative HSV image in matlab

I want to create an HSV image (or maybe a coordinate map) which shows that coordinates accurately.
I am using the following code and get an image like this the result of the following code which is not what I want.
img = rand(200,200);
[ind_x, ind_y] = ind2sub(size(img),find(isfinite(img)));
ind_x = reshape(ind_x,size(img));
ind_y = reshape(ind_y,size(img));
ind = ind_x.*ind_y;
figure, imagesc(ind); axis equal tight xy
Lets say you quantize the HSV space (0-1) into 256 bins. There will be 256*256*256 possible colors. We could fix a dimension (say saturation) and generate the matrix. Then there will be 256*256 colors.
[x1,x2]=meshgrid(linspace(0,1,256),linspace(0,1,256));
img(:,:,1)=x1;
img(:,:,2)=1; %fully saturated colors
img(:,:,3)=x2;
imgRGB=hsv2rgb(img); %for display purposes
imshow(imgRGB,[])
It will look different in RGB (that's where you would visualize). It looks similar to your image if you visualize HSV matrix (i.e. without converting it to RGB, but MATLAB doesn't know that its HSV)
imshow(img,[]);
The second image you have posted can be obtained with:
[x1,x2]=meshgrid(linspace(0,1,256),linspace(0,1,256));
img(:,:,1)=x1;
img(:,:,2)=0;
img(:,:,3)=x2;
imshow(img,[]) %visualizing HSV

Extracting numerical data from an intensity printout

I'm looking to create an intensity matrix in Matlab from an intensity image plot (saved as a jpeg (RGB) file) that was made using what appears to be the jet colormap from Matlab. I am essentially trying to reverse engineer the numerical data from the plot. The original image along with the color bar is linked (I do not have enough reputation to insert images).
http://i.imgur.com/BmryO6W.png
I initially thought this could be done with the rgb2gray command, but it produces the following image with the jet colormap applied which does not match the original image.
http://i.imgur.com/RlBei2z.png
As far as I can tell, the only route available from here is to try matching the RGB value for each pixel to a value in the colormap lookup table. Any suggestions on if this the fastest approach?
It looks like your method using rgb2gray is almost working, apart from the scale. Because the colormap is scaled automatically to the contents of your plot, I think you will have to re-scale it manually (unless you can automatically detect the tick labels on the colorbar). You can do this using the following formula:
% Some random data like yours
x = rand(1000) * 256;
% Scale data to fit your range
xRange = [min(x(:)) max(x(:))];
scaleRange = [-10 10];
y = (x - xRange(1)) * diff(scaleRange) / diff(xRange) + scaleRange(1);
You can check the operation's success with
>> [min(y(:)) max(y(:))]
ans =
-10 10

How to lock image dimensions in MATLAB

So I have this matrix in MATLAB, 200 deep x 600 wide. It represents an image that is 2cm deep x 6cm wide. How can I plot this image so that it is locked into proper dimensions, i.e. 2cm x 6cm? If I use the image or imagesc commands it stretches it all out of shape and shows it the wrong size. Is there a way to lock it into showing an image where the x and y axes are proportional?
Second question, I need to then set this image into a 640x480 frame (20 pixel black margin on left and right, 280 pixel black margin on bottom). Is there a way to do this?
To keep aspect ratio, you can use axis equal or axis image commands.
Quoting the documentation:
axis equal sets the aspect ratio so that the data units are the same in every direction. The aspect ratio of the x-, y-, and z-axis is adjusted automatically according to the range of data units in the x, y, and z directions.
axis image is the same as axis equal except that the plot box fits tightly around the data`
For second question:
third_dimension_size=1; %# for b&w images, use 3 for rgb
framed_image=squeeze(zeros(640,480,third_dimension_size));
framed_image(20:20+600-1,140:140+200-1)= my_600_200_image;
imagesc(framed_image'); axis image;
set(gca,'DataAspectRatio',[1 1 1])
Second question:
new_image = zeros(480,640);
new_image(20:(200+20-1),20:(600+20-1)) = old_image;
As an alternative to the other answers, you might want:
set(gca, 'Units', 'centimeters', 'Position', [1 1 6 2])
Make sure you do this after plotting the image to get the other axis properties correct.
For the second question, take care with the number of colour channels:
new_image = zeros(480,640, size(old_image));
new_image(20:(200+20-1),20:(600+20-1),:) = old_image;

Resources