I found a code about image rotation in frequency domain. But I couldn't understand this code. This code works correct. Can anyone describe this code? Actually I have to write a code to rotate an image in frequency domain in polar coordinates. Do you think this code
meet the requirements.
clear;
img=imread('cameraman.tif');
imshow(img); title('original image');
theta=26,5;
N=size(img,1);
M=size(img,2);
fimg=fftshift(fft2(fftshift(img)));
p=ones(N,1)*[-N/2:(N-1)/2]; % horizontal axis
q=-p'; % vertical axis
theta=2*pi*theta/360;
g=1/(N^2).*fimg;
z1=exp(i*pi/N.*((p.^2-q.^2)*cos(theta)-2*p.*q*sin(theta)));
z2=exp(-i*pi/N.*((p.^2-q.^2)*cos(theta)-2*p.*q*sin(theta)));
k=ifft2(fft2(g.*z1).*(fft2(z2)));
figure,
imshow(abs(fftshift(flipud(k))), [0 255]);
title(['Cameraman rotated at ' num2str(theta*360/(2*pi)) ' Degrees']); axis off
As you can see here.
For the rotation, there is no properties. But this code using the shift properties to apply the rotation.
In z1, you have the coordinate (p,q) compute normaly as well, but just by applying the 2D rotation matrix to your coordinate, you can use the shift properties.
And notice, this code change a the sign every where, that why there no minus in z1 instead of z2.
Rotation : [cos(theta) -sin(theta);
sin(theta) cos(theta)];
Related
A similar question was asked before, unfortunately I cannot comment Samgaks answer so I open up a new post with this one. Here is the link to the old question:
How to calculate ray in real-world coordinate system from image using projection matrix?
My goal is to map from image coordinates to world coordinates. In fact I am trying to do this with the Camera Intrinsics Parameters of the HoloLens Camera.
Of course this mapping will only give me a ray connecting the Camera Optical Centre and all points, which can lie on that ray. For the mapping from image coordinates to world coordinates we can use the inverse camera matrix which is:
K^-1 = [1/fx 0 -cx/fx; 0 1/fy -cy/fy; 0 0 1]
Pcam = K^-1 * Ppix;
Pcam_x = P_pix_x/fx - cx/fx;
Pcam_y = P_pix_y/fy - cy/fy;
Pcam_z = 1
Orientation of Camera Coordinate System and Image Plane
In this specific case the image plane is probably at Z = -1 (However, I am a bit uncertain about this). The Section Pixel to Application-specified Coordinate System on page HoloLens CameraProjectionTransform describes how to go form pixel coordinates to world coordinates. To what I understand two signs in the K^-1 are flipped s.t. we calculate the coordinates as follows:
Pcam_x = (Ppix_x/fx) - (cx*(-1)/fx) = P_pix_x/fx + cx/fx;
Pcam_y = (Ppix_y/fy) - (cy*(-1)/fy) = P_pix_y/fy + cy/fy;
Pcam_z = -1
Pcam = (Pcam_x, Pcam_y, -1)
CameraOpticalCentre = (0,0,0)
Ray = Pcam - CameraOpticalCentre
I do not understand how to create the Camera Intrinsics for the case of the image plane being at a negative Z-coordinate. And I would like to have a mathematical explanation or intuitive understanding of why we have the sign flip (P_pix_x/fx + cx/fx instead of P_pix_x/fx - cx/fx).
Edit: I read in another post that the thirst column of the camera matrix has to be negated for the case that the camera is facing down the negative z-direction. This would explain the sign flip. However, why do we need to change the sign of the third column. I would like to have a intuitive understanding of this.
Here the link to the post Negation of third column
Thanks a lot in advance,
Lisa
why do we need to change the sign of the third column
To understand why we need to negate the third column of K (i.e. negate the principal points of the intrinsic matrix) let's first understand how to get the pixel coordinates of a 3D point already in the camera coordinates frame. After that, it is easier to understand why -z requires negating things.
let's imagine a Camera c, and one point B in the space (w.r.t. the camera coordinate frame), let's put the camera sensor (i.e. image) at E' as in the image below. Therefore f (in red) will be the focal length and ? (in blue) will be the x coordinate in pixels of B (from the center of the image). To simplify things let's place B at the corner of the field of view (i.e. in the corner of the image)
We need to calculate the coordinates of B projected into the sensor d (which is the same as the 2d image). Because the triangles AEB and AE'B' are similar triangles then ?/f = X/Z therefore ? = X*f/Z. X*f is the first operation of the K matrix is. We can multiply K*B (with B as a column vector) to check.
This will give us coordinates in pixels w.r.t. the center of the image. Let's imagine the image is size 480x480. Therefore B' will look like this in the image below. Keep in mind that in image coordinates, the y-axis increases going down and the x-axis increases going right.
In images, the pixel at coordinates 0,0 is in the top left corner, therefore we need to add half of the width of the image to the point we have. then px = X*f/Z + cx. Where cx is the principal point in the x-axis, usually W/2. px = X*f/Z + cx is exactly as doing K * B / Z. So X*f/Z was -240, if we add cx (W/2 = 480/2 = 240) and therefore X*f/Z + cx = 0, same with the Y. The final pixel coordinates in the image are 0,0 (i.e. top left corner)
Now in the case where we use z as negative, when we divide X and Y by Z, because Z is negative, it will change the sign of X and Y, therefore it will be projected to B'' at the opposite quadrant as in the image below.
Now the second image will instead be:
Because of this, instead of adding the principal point, we need to subtract it. That is the same as negating the last column of K.
So we have 240 - 240 = 0 (where the second 240 is the principal point in x, cx) and the same for Y. The pixel coordinates are 0,0 as in the example when z was positive. If we do not negate the last column we will end up with 480,480 instead of 0,0.
Hope this helped a little bit
I would like to know how to rotate a 2D image along its Z-axis using Matlab R2016b and to obtain an image after performing this procedure.
For example, let's take this 2D image:
Now, I rotate it of 45° roughly:
And now, of 90°:
Do you know if it is possible to perform the same operation in Matlab R2016b, please ?
Thank you very much for your help
Images Source: https://www.youtube.com/watch?v=m89mVexWQZ4
Yes it's possible. The easiest thing to do would be to map the image on the y = 0 plane in 3D, then rotate the camera to the desired azimuth or the angle with respect to the y axis. Once you do that, you can use the getframe / cdata idiom to actually capture the actual image data in a variable itself. The reason why you do this with respect to the y plane is because the method that I will be using to present the image is through the surf command that plots surface plots in 3D, but the y axis here is the axis that goes into and out of the screen. The x axis is the horizontal and the z axis would be the vertical when displaying data.
First read in your image using something like imread, then you need to define the 4 corners of the image that map to the 3D plane and then rotate the camera. You can use the view function to help you rotate the camera by adjusting the azimuthal angle (first parameter) and leaving the elevation angle as 0.
Something like this could work. I'll be using the peppers image that is part of the image processing toolbox:
im = imread('peppers.png'); % Read in the image
ang = 45; % Rotate clockwise by 45 degrees
% Define 4 corners of the image
X = [-0.5 0.5; -0.5 0.5];
Y = [0 0; 0 0];
Z = [0.5 0.5; -0.5 -0.5];
% Place the image on the y = 0 plane
% Turn off the axis and rotate the camera
figure;
surf(X, Y, Z, 'CData', im, 'FaceColor', 'texturemap');
axis('off');
view(ang, 0);
% Get the image data after rotation
h = getframe;
rot_im = h.cdata;
rot_im contains the rotated image. To appreciate the rotation of the image, we can loop through angles from 0 to 360 in real time. At each angle, we can use view to dynamically rotate the camera and use drawnow to update the figure. I've also updated the title of the figure to show you what the angle is at each update. The code for that is below as well as the output saved as an animated GIF:
for ang = 0 : 360
view(ang, 0);
pause(0.01);
drawnow;
title(sprintf('Angle: %d degrees', ang));
end
For an ellipsoid of the form
with orientation vector and centre at point , how to find whether a point is inside the ellipsoid or not?
An additional note that the geometry actually is with a=b (spheroid) and therefore one axis is sufficient to define orientation
Note: I see a similar question asked in the forum. But, it is about an ellipsoid at origin and without any arbitrary orientation and here both arbitrary position and orientation are considered.
Find affine transform M that translates this ellipse in axis-oriented one (translation by -p and rotation to align orientation vector r and proper coordinate axis).
Then apply this transform to point p and check that p' lies inside axis-oriented ellipsoid, i.e.
x^2/a^2+ y^2/b^2+z^2/c^2 <= 1
Create a coordinate system E with the center at p and with the long axis of the ellipse aligned with r. Create a matrix that can transform global coordinates to the coordinate system E. Then put the transformed coordinates into the ellipse equation.
A center point p and an "orientation vector" r do not suffice to completely specify the position of the ellipsoid, there is one degree of freedom left. Your problem is indeterminate.
If your vector r is a unit vector from the origin to the pole, then the test for whether a point q is in (or on) the ellipse is:
v = q-p; // 3d vector difference
dot = v.r; // 3d dot product
f = dot*dot;
g = v.v - f; // 3d dot product and scalar subtraction
return f/(b*b) + g/(a*a) <= 1
Note that if the ellipse was aligned so that r was the z unit vector, then the test above translates into the usual test for inclusion of a point in an ellipse.
I am new to Matlab. I have an image (the size is mxnx3) with a few human-selected points on the image. For example:
p1 = [267,79];
p2 = [96,372];
These points are image coordinates with (1,1) at the top left. I'm trying to convert this to Cartesian coordinates with (0,0) on the bottom left. How can I do this? Thanks in advance!
If I understand correctly: just use
axis xy
From axis doc:
AXIS XY puts MATLAB into its default "Cartesian" axes mode. The
coordinate system origin is at the lower left corner. The x
axis is horizontal and is numbered from left to right. The y
axis is vertical and is numbered from bottom to top.
If you need to directly translate your co-ordinates in code, you could make a simple anonymous function:
img2cart = #(p) [p(1), img.size(2) - p(2)];
q1 = img2cart(p1);
q2 = img2cart(p2);
I have a plain bitmap and I want to do a projection on a cylinder.
That means, I want to transform the image in a way so that if I print it and wrap around a columnar cylinder and photograph it from a certain position, the resulting image looks like the original.
Still I'm quite lost in all the projection algorithms (that are often related to earth projections).
So I'd be thankful for hints what the correct algorithm could be and which tools I could use to apply it to my image.
Let say you have a rectangle image of lenght: L and height: H .
and a cylinder of radius : R and height H'
Let A (x,z) be a point in the picture,
Then A' (x',y',z') = ( R*cos(x*(2Pi/L)) , R*sin(x*(2Pi/L)) , z*(H'/H)) will be the projection of your point A on your cylinder.
Proof :
1. z' = z*(H'/H)
I first fit the cylinder to the image size , that's why I multiply by
: (H'/H), and I keep the same z axis. (if you draw it you will see it
immediatly)
2. x' and y ' ?
I project each line of my image into a circle . the parametric
equation of a circle is (Rcos(t), Rsin(t)) for t in [0,2PI], the
parametric equation map a segment (t in [0,2PI]) to a circle . That's
exactly what we are trying to do.
then if x describes a line of lenght L, x*(2pi)/L describres a line of
length 2pi and I can use the parametric equation to map each point of
this line to a circle.
Hope it helps
The previous function gave the function to "press" a plane against a cylinder.
This is a bijection, so from a given point in the cylinder you can easily get the original image.
A(x,y,z) from the cylinder
A'(x',z') in the image :
z' = z*(H/H')
and x' = L/(2Pi)* { arccos(x/R) *(sign(y)) (mod(2Pi)) }
(it's a pretty ugly formula but that's it :D and you need to express the modulo as a positive value)
If you can apply that to your cylindrical image you get how to uncoil your picture.