I am trying to find the shape of a curve shape rod in its plane, based on two perpendicular views of the rod. I have prepared an image to make my question clearer.
I have the projected images of the rod on the planes 1 and 2, and I'd like to produce the image of the rod in plane 3. What I have done is that I found the center line of the rod on views 1 and 2 using Matlab image processing toolbox, then I fitted a curve on those lines. Then I produced 3D data based on those fitted curves, and finally fitted another curve or ellipse to the final 3D curve.
It works, but I am wondering if there is any more appropriate solution, for example by rotating the views 1 and 2.
The angle of the view 3 with respect to view 1 (and view 2) is variable, but views 1 and 2 are perpendicular to each other.
We can find the angle of the plane 3 by finding the end of the rod in the views 1 and 2, as it would be atan(x_end_in_view_1/x_end_in_view_two). Is it possible to produce the image from the view point of a camera angled to a known degree from another camera, based on the image from the second camera?
Any help is highly appreciated.
Yes, it is possible to produce the image from the view point of a camera angled to a known degree from another camera. Given the angle, you can compute the affine transformation between the two planes and apply the transformation to the original image to get the projection of the image in another plane.
There are 6 parameters for an affine transformation, and since you know the angle between the two planes, for 4 points (0, 0), (0, 1), (1, 0) and (1, 1), you would know the (x, y) co-ordinates of these points after you tilt your plane (say about the y axis) (forget about the z-coordinate). Now, you will have 8 equations and 6 unknowns, hence you can compute the affine transformation and apply the transformation on the complete image to get the projection.
Related
If a camera is looking at say 6 evenly spaced dots in the real world it would look like the image below if the camera is looking at the image straight on with no rotation in the x, y or z axis
The z-axis is perpendicular to the image sensor so rotation around the z-axis is simple, it's just a tilt of the image. If I were to rotate the camera (or objects being looked at) around the x axis (if the x-axis is up down) the rows and columns will no longer be parallel and would project off to a vanishing point, like this.
What I would like to do is take a 2 dimensional image of say, dots, and be able to apply different rotations around the x,y and z axes independently. I've experimented with reading my image in Matlab and multiplying by a rotation matrix, or even a full camera matrix but I can't figure out how to take a 2D image, simulate rotating it around the x axis and then saving that back to an image. So that my original grid of dots would look like the bottom image with lines going off to a vanishing point. I've seen some examples using imwarp but I didn't see how I can set the angle of rotation. I'm working on camera calibration so I really want to be able to specify an angle of rotation around each axis.
Thanks for any help.
Basically, I have a many irregular circle on the ground in the form of x,y,z coordinates (of 200*3 matrix). but I want to fix a best circle in to the data of x,y,z coordinates (of 200*3 matrix).
Any help will be greatly appreciated.
I would try using the RANSAC algorithm which finds the parameters of your model (in your case a circle) given noisy data. The algorithm is quite easy to understand and robust against outliers.
The wikipedia article has a Matlab example for fitting a line but it shouldn't be too hard to adapt it to fit a circle.
These slides give a good introduction to the RANSAC algorithm (starting from page 42). They even show examples for fitting a circle.
Though this answer is late, I hope this helps others
To fit a circle to 3d points
Find the centroid of the 3d points (nx3 matrix)
Subtract the centroid from the 3D points.
Using RANSAC, fit a plane to the 3D points. You can refer here for the function to fit plane using RANSAC
Apply SVD to the 3d points (nx3 matrix) and get the v matrix
Generate the axes along the RANSAC plane using the axes from SVD. For example, if the plane norm is along the z-direction, then cross product between the 1st column of v matrix and the plane norm will generate the vector along the y-direction, then the cross product between the generated y-vector and plane norm will generate a vector along the x-direction. Using the generated vectors, form a Rotation matrix [x_vector y_vector z_vector]
Multiply the Rotation matrix with the centroid subtracted 3d points so that the points will be parallel to the XY plane.
Project the points to XY plane by simply removing the Z-axes from the 3d points
fit a circle using Least squares circle fit
Rotate the center of the circle using the inverse of the rotation matrix obtained from step 5
Translate back the center to the original location using the centroid
The circle in 3D will have the center, the radius will be the same as the 2D circle we obtained from step 8, the circle plane will be the RANSAC plane we obtained from step 3
stereoParameters takes two extrinsic parameters: RotationOfCamera2 and TranslationOfCamera2.
The problem is that the documentation is a not very detailed about what RotationOfCamera2 really means, it only says: Rotation of camera 2 relative to camera 1, specified as a 3-by-3 matrix.
What is the coordinate system in this case ?
A rotation matrix can be specified in any coordinate system.
What does it exactly mean "the coordinate system of Camera 1" ? What are its x,y,z axes ?
In other words, if I calculate the Essential Matrix, how can I get the corresponding RotationOfCamera2 and TranslationOfCamera2 from the Essential Matrix ?
RotationOfCamera2 and TranslationOfCamera2 describe the transformation from camera1's coordinates into camera2's coordinates. A camera's coordinate system has its origin at the camera's optical center. Its X and Y-axes are in the image plane, and its Z-axis points out along the optical axis.
Equivalently, the extrinsics of camera 1 are identity rotation and zero translation, while the extrinsics of camera 2 are RotationOfCamera2 and TranslationOfCamera2.
If you have the Essential matrix, you can decompose it into the rotation and a translation. Two things to keep in mind. First, the translation is up to scale, so t will be a unit vector. Second, the rotation matrix will be a transpose of what you get from estimateCameraParameters, because of the difference in the vector-matrix multiplication conventions.
Out of curiosity, what is it that you are trying to accomplish? Are you working with a single moving camera? Otherwise, why not use the Stereo Camera Calibrator app to calibrate your cameras, and get rotation and translation for free?
Suppose for left camera's 1st checkerboard (or to any world reference) rotation is R1 and translation is T1, right camera's 1st checkerboard rotation is R2 and translation is T2, then you can calculate them as follows;
RotationOfCamera2 = R2*R1';
TranslationOfCamera2= T2-RotationOfCamera2*T1
But please note that this calculations are just for one identical checkerboard reference. Inside matlab these two parameters are calculated by all given pair of checkerboard images and calculate median values as initial guess. Later these parameters will be refine by nonlinear optimization. So after median calculations they might be sigtly differ. But if you have just one reference point tranfomation for both two camera, you should use above formula. Note Dima told, matlab's rotation matrix is transpose of normal usage. So I wrote it as how the literature tells not matlab's style.
so I have created a circle with draw method :
glLineWidth(16);
glColor4ub(0, 255, 0, 255);
drawCircle( ccp(s.width/2, s.height/2), 100, 0, 10, NO);
I would like to know if it is possible to transform this shape to a rectangle shape with animation . Thank you . sorry for my english I'm french :/
For simplicity, I'd use 4 cubic bezier curves - one curve per quadrant of the circle. (This isn't a perfect circle but neither is a 100 segment circle!) Then, using the schedule: functionality provided by cocos2d, I would gradually move each curve's control points over time until they line-up vertically or horizontally with the curve's origin and destination. This turns the curves into 4 straight lines: a rectangle!
Well, a square to be exact. You'll also have to move the origins and destinations of all 4 curves to form a rectangle that is not a square, but you get the idea I hope?
See these links for additional info:
Bezier Circle math - http://www.cgafaq.info/wiki/Bezier_Circle
cocos2d - ccDrawCubicBezier - http://www.cocos2d-iphone.org/api-ref/2.0.0/_c_c_drawing_primitives_8h.html#a5a391711c0aa611a06167bdd7637571f
cocos2d - schedule: example code - http://www.cocos2d-iphone.org/wiki/doku.php/prog_guide:lesson_2._your_first_game#making_things_move
EDIT: added image
d = d value calculated from equation at: http://www.cgafaq.info/wiki/Bezier_Circle
start, control 1, control 2, and end are the 4 points needed to make a cubic bezier curve in cocos2d.
You will have to write the code for this.
You could, for example, create a number of control points that are around the circle. Each of these control points could consist of 3 points. Two points that represent two points on the circle and one point that controls the curve of the line drawn between the two points. Now you animate the motion between the control points on the curve such that they move to become the control points on a rectangle and at the same time animate the motion of the third control point so the edge changes from a curve to a straight line.
I have a 3D matrix of data in matlab, but I want to extract an arbitrarily rotated slice of data from that matrix and store it as a 2D matrix, which I can access. Similar to how the slice() function displays data sliced at any angle, except I would also like to be able to view and modify the data as if it were an array.
I have the coordinates of the pivot-point of the plane as well as the angles of rotation (in x, y and z axis), I have also calculated the equation of the plane in the form:
Ax + By + Cz = D
and can extract a 3D matrix containing only the data that fall on that plane, but I don't know how to then convert that into a simple 2D array.
Another way of doing it would be to somehow rotate the source matrix in the opposite direction of the angle of the plane, so as to line up the plane of data with the XY axis, and simply extract that portion of the matrix, but I do not know if rotating a matrix like that is possible.
I hope this hasn't been answered elsewhere, I've been googling it all day, but none of the problems seem to exactly match mine.
Thanks
You can take a look at the code here. I think the function is similar to what you are trying to solve.
The function extracts an arbitrary plane from a volume given the size of the plane, the center point of the plane, and the plane normal, i.e. [A,B,C]. It also outputs the volumetric index and coordinate of each pixel on the plane.
Aha! May have just solved it myself.
To produce the plane equation I rotate a normal vector of (0,0,1) using rotation matrices and then find D. If I also rotate the following vectors:
(1,0,0) //step in the x direction of our 2D array
and
(0,1,0) //step in the y direction of our 2D array
I'll have the gradients that denote how much my coordinates in x,y,z have to change before I step to the next column in my array, or to the next row.
I'll mock this up ASAP and mark it as the answer if it works
EDIT: Ok slight alteration, when I'm rotating my vectors I should also rotate the point in 3D space that represents the xyz coordinates of x=0,y=0,z=0 (although I'm rotating around the centre of the structure, so it's actually -sizex/2,-sizey/2,-sizez/2, where size is the size of the data, and then I simply add size/2 to each coordinate after the rotations to translate it back to where it should be).
Now that I have the gradient change in 3D as I increase the x coordinate of my 2D array and the gradient change as I increase the y coordinate, I can simply loop through all possible x and y coordinates (the resulting array will be 50x50 for a 50x50x50 array, I'm not sure what it will be for irregular sizes, which I'll need to work out eventually) in my 2D array and calculate the resulting 3D coordinates on my plane in the data. My rotated corner value serves as the starting point. Hooray!
Just got to work out a good test for this encompassing all angles and then I'll approve this as an answer