RGB = imread('originalimg.png');
MyImrgb = reshape(im2double(RGB), [],3);
Imrgb = MyImrgb.^2.2; %gamma correction
[x, y, z] = size(Imrgb);
% ld % rg %yv
ldrgyv2rgbMat = [1,1,0.236748566577269;
1,-0.299338211934457,-0.235643322285071;
1,0.0137437185685517,1]; % B
MyImrgbCol = reshape(Imrgb * ldrgyv2rgbMat, size(RGB));
MyImldrgyvCol = reshape(reshape(MyImrgbCol, [],3) *inv(ldrgyv2rgbMat),size(MyImrgbCol));
imshow(MyImldrgyvCol)
I need to find the white point in the color image in a particular axis say x axis. How do I proceed about it?
In an image, every axis has its own color. The transition point from that color, say for example red to green, the midpoint would be the white point. How do I write a Matlab code to get that point?
Related
I'm trying to color code some parameter values on a gray image in MATLAB. I'm wondering how to show gray image, make parameter values colored on the gray appearance image and on some pixels, and finally draw a colorbar aside the image just showing parameter values range.
Unsuccessful Code since now:
I = Igray; % gray image
Icc = zeros(size(I,1),size(I,2),3); % color coded image
Icc(:,:,1) = I;
Icc(:,:,2) = I;
Icc(:,:,3) = I;
Icc('some address in the image',3) = 'some number between 0 and 255';
imshow(Icc,[])
colorbar % colorbar showing colored parts spectrum
Result image that I need:
Try something like this:
I = Igray; % gray image
RGB = [1.0,0.7,0.2]; % color for patch
x = 30:50;
y = 70:90;
% If you gray image is in the range [0,255], make it range [0,1]
I = double(I)/255;
Icc = repmat(I,[1,1,3]);
block = I(y,x);
Icc(y,x,1) = 1 - ((1-block) * (1-RGB(1)));
Icc(y,x,2) = 1 - ((1-block) * (1-RGB(2)));
Icc(y,x,3) = 1 - ((1-block) * (1-RGB(3)));
imshow(Icc)
I'm sure there is a prettier way to encode this, but this way it shows the intent.
You're basically multiplying the grey values with the RGB color you want to make the patch. By inverting the patch and the color first, and inverting the result, the multiplication makes the patch brighter, not darker. That way you get the effect you want where the dark parts show the color also. If you multiply directly without inverting first, black stays black and doesn't show the color.
You'll have to figure out how to coordinate with the color bar after that. There are commands in MATLAB to set the limits of the color bar, you can find those reading the documentation.
The color bar you show uses the PARULA color map. You could do this to find the right RGB value to color your patch:
T; % value to color your patch in, in range [0,1]
cm = parula(256);
RGB = interp1(cm,T*255,'linear')
I want to make a circle inside a matrix. For example; Make a matrix of some dimension, let's say ones(200,200) and then select its circle's x and y co-ordinates and change the color of these selected pixels and then show the image using imshow(img). As showing in the picture. Is it possible?
OR
Can I change this ploting code to picture for using the circle functionality?
radius = 5;
centerX = 20;
centerY = 30;
viscircles([centerX, centerY], radius);
axis square;
You can use meshgrid to create a grid of x and y coordinates and then use the equation of the circle to check whether each x/y pair is within the circle or not. This will yield a logical result which can be displayed as an image
[x,y] = meshgrid(1:200, 1:200);
isinside = (x - centerX).^2 + (y - centerY).^2 <= radius^2;
imshow(isinside);
If you simply want the outline of the circle, you can apply a convolution to the resulting binary mask to decrease it's size and then subtract out the circle to yield only the outline
shrunk = ~conv2(double(~isinside), ones(3), 'same');
outline = isinside - shrunk;
imshow(outline)
If you have the Image Processing Toolbox, you can use bwperim to yield the binary outline
outline = bwperim(isinside);
imshow(outline);
Update
If you want to change the colors shown above, you can either invert outline and isinside before displaying
isinside = ~isinside;
outline = ~outline;
imshow(isinside)
imshow(outline)
Or you can invert the colormap
imshow(isinside)
colormap(gca, flipud(gray))
As part of a circle recognition program, I have a background image with a geometrical circle with known coordinates and radius. I want the inside part of the circle filled by an image and the outside left alone. My best idea is some sort of circular mask, but I am not sure this is the best approach. Any suggestions?
X = imread('X.jpg'); % Background image jpg
Y = imread('Y.jpg'); % Filling image jpg
cent = [100,100]; % Center of circle
rad = 20; % Circle radius
% Fill circle ?
...
I have not provided the extended code, due to confidentiality.
I think the hard part was done by whomever authored this: http://matlab.wikia.com/wiki/FAQ#How_do_I_create_a_circle.3F
Assumptions:
I'm assuming you're not going to specify points that are out of range of the image (i.e. I'm not adding validation here).
I use the background image to relate the "center" of your circle to the coordinates.
I'm assuming radius is in pixels.
I didn't create a background image with a circle of known radius because I don't think that's necessary to create the filling effect you're looking for (unless I'm missing something).
Code:
X = imread('rdel_x.png'); % Background image jpg (I used a random image but this can be your blank + geometric circle)
Y = imread('rdel_y.png'); % Filling image jpg
cent = [100,150]; % Center of circle
rad = 70; % Circle radius
% make a mesh grid to provide coords for the circle (mask)
% taken from http://matlab.wikia.com/wiki/FAQ#How_do_I_create_a_circle.3F
[columnsInImage rowsInImage] = meshgrid(1:size(X,2), 1:size(X,1));
% circle points in pixels:
circlePixels = (rowsInImage - cent(1)).^2 ...
+ (columnsInImage - cent(2)).^2 <= rad.^2;
circlePixels3d=repmat(circlePixels,[1 1 3]); % turn into 3 channel (assuming X and Y are RGB)
X((circlePixels3d)) = Y((circlePixels3d)); % assign the filling image pixels to the background image for pixels where it's the desired circle
imagesc(X);
axis image off
Result: from left to right, background image, filling image, result from above code.
Edit: you might not even need the background image if everything is encapsulated in your coordinates. e.g. try appending this to the above code...
Z=zeros(size(X),'uint8'); % same size as your background
Z(circlePixels3d) = Y(circlePixels3d);
figure; % new fig
imagesc(Z);
axis image off
I want to draw a circle with perspective tansformation in Matlab. Here I have used sample of code to draw a circle. If I rotate this circle using perspective tansform this must be ellipse. I want to draw both axis rotation(X & Y) of a circle. Now I am struggled to draw a perspetive rotation of this circle.
I need to use radious of the circle, x axis roation angle and y axis roation angle as input parameters.
Rimg = zeros(600,600);
ri = 100;
xcentre = 300;
ycentre = 300;
for r = 0:ri
for rad = 0:(pi/720):(2*pi)
xi = round(xcentre+(r*cos(rad)));
yi = round(ycentre+(r*sin(rad)));
Rimg(xi,yi) = 1;
end
end
imshow(Rimg,[]);
The first image shows my circle and the second image shows the expected result. This is only rotated in x axis. But I need both axis rotation in a single image.
I have two images. One is the original, and the another is rotated.
Now, I need to discover the angle that the image was rotated. Until now, I thought about discovering the centroids of each color (as every image I will use has squares with colors in it) and use it to discover how much the image was rotated, but I failed.
I'm using this to discover the centroids and the color in the higher square in the image:
i = rgb2gray(img);
bw = im2bw(i,0.01);
s = regionprops(bw,'Centroid');
centroids = cat(1, s.Centroid);
colors = impixel(img,centroids(1),centroids(2));
top = max(centroids);
topcolor = impixel(img,top(1),top(2));
You can detect the corners of one of the colored rectangles in both the image and the rotated version, and use these as control points to infer the transformation between the two images (like in image registration) using the CP2TFORM function. We can then compute the angle of rotation from the affine transformation matrix:
Here is an example code:
%# read first image (indexed color image)
[I1 map1] = imread('http://i.stack.imgur.com/LwuW3.png');
%# constructed rotated image
deg = -15;
I2 = imrotate(I1, deg, 'bilinear', 'crop');
%# find blue rectangle
BW1 = (I1==2);
BW2 = imrotate(BW1, deg, 'bilinear', 'crop');
%# detect corners in both
p1 = corner(BW1, 'QualityLevel',0.5);
p2 = corner(BW2, 'QualityLevel',0.5);
%# sort corners coordinates in a consistent way (counter-clockwise)
p1 = sortrows(p1,[2 1]);
p2 = sortrows(p2,[2 1]);
idx = convhull(p1(:,1), p1(:,2)); p1 = p1(idx(1:end-1),:);
idx = convhull(p2(:,1), p2(:,2)); p2 = p2(idx(1:end-1),:);
%# make sure we have the same number of corner points
sz = min(size(p1,1),size(p2,1));
p1 = p1(1:sz,:); p2 = p2(1:sz,:);
%# infer transformation from corner points
t = cp2tform(p2,p1,'nonreflective similarity'); %# 'affine'
%# rotate image to match the other
II2 = imtransform(I2, t, 'XData',[1 size(I1,2)], 'YData',[1 size(I1,1)]);
%# recover affine transformation params (translation, rotation, scale)
ss = t.tdata.Tinv(2,1);
sc = t.tdata.Tinv(1,1);
tx = t.tdata.Tinv(3,1);
ty = t.tdata.Tinv(3,2);
translation = [tx ty];
scale = sqrt(ss*ss + sc*sc);
rotation = atan2(ss,sc)*180/pi;
%# plot the results
subplot(311), imshow(I1,map1), title('I1')
hold on, plot(p1(:,1),p1(:,2),'go')
subplot(312), imshow(I2,map1), title('I2')
hold on, plot(p2(:,1),p2(:,2),'go')
subplot(313), imshow(II2,map1)
title(sprintf('recovered angle = %g',rotation))
If you can identify a color corresponding to only one component it is easier to:
Calculate the centroids for each image
Calculate the mean of the centroids (in x and y) for each image. This is the "center" of each image
Get the red component color centroid (in your example) for each image
Subtract the mean of the centroids for each image from the red component color centroid for each image
Calculate the ArcTan2 for each of the vectors calculated in 4), and subtract the angles. That is your result.
If you have more than one figure of each color, you need to calculate all possible combinations for the rotation and then select the one that is compatible with the other possible rotations.
I could post the code in Mathematica, if you think it is useful.
I would take a variant to the above mentioned approach:
% Crude binarization method to knock out background and retain foreground
% features. Note one looses the cube in the middle
im = im > 1
Then I would get the 2D autocorrelation:
acf = normxcorr2(im, im);
From this result, one can easily detect the peaks, and as rotation carries into the autocorrelation function (ACF) domain, one can ascertain the rotation by matching the peaks between the original ACF and the ACF from the rotated image, for example using the so-called Hungarian algorithm.