i am using opencv to take measurements in meters from point A to point B with the formula of the distance between points in 3d in the real world.
sqrt( (Bx - Ax)² + (By - Ay)² + (Bz - Az)² )
I made the calibration code, after I use the reprojectImageTo3D (point cloud) function providing the the calibration matrix and the disparity map to get the measurements in meters.
Except that the reproject3d function gives me an array with negative values on both the x axis and the z axis. Is it correct that the function returns negative values?
If not, what did I do wrong to get measurements in meters?
Related
Following is the conversion for spherical to cartesian coordinate
X = r cosθ sinΦ
Y = r sinθ sinΦ
Z = rcosΦ
we are using the reverse computation to compute spherical coordinate from cartesian coordinate which is defined as
r = √(x^2+y^2+z^2 )
θ = atan(Y./X)
Φ = atan(√(X^2+Y^2 )./Z)
The problem arises when Y and X are zero so θ can take any arbitrary value so during Matlab computations this results in NAN(not a number ) which makes θ discontinuous. Is there any interpolation technique to remove this discontinuity and how to interpret θ in this case.
θ is a matrix at various point and it gives following result it has jumps and black patched that represent discontinuity whereas I need to generate the following image with smooth variation. Please see the obtained theta and correct theta variation by clicking on the link and suggest some changes.
Discontinuous_Theta_variation
Correct Theta variation
While doing conversion from Cartesian to Spherical coordinate system, however the formulas which are written here are correct but you first need to understand their physical significance.
'r' is the distance of the point from origin. θ is the angle from the positive x axis to the line which is made by projecting the given point to XY plane. And Φ being the angle from positive z-axis to the line which joins origin and given point.
http://www.learningaboutelectronics.com/Articles/Cartesian-rectangular-to-spherical-coordinate-converter-calculator.php#answer
So say, for a point which has X and Y coordinates as 0, that means it lies on z axis and hence, its projection on XY plane lies on the origin. So we cannot exactly determine the angle of origin from X axis. But please note that, since the point lies on Z axis, so Φ=0 or pi (depending whether Z is positive or negative).
So while coding this problem, you may adapt this approach that you first check for Φ, if it is 0 or pi then theta = 0 (by default).
I hope this serves the purpose.
I have followed the stereo implementation from book "Learning OpenCV". I have the fundamental, essential, rotation, translation matrices and how do I calculate the real world position of an object that I have clicked on?
You can use ReprojectTo3D.
The reprojectImageto3D function requires the disparity map, an output array of the same size of the image & an array Q (disparity-to-depth map).
Q is calculated from stereoRectify function -> stereoRectify requires the intrinsic camera matrices, distortion coefficients & the relative rotation & translation vectors between the 2 cameras (R&T).
To calculate all these, use the stereoCalibrate function which outputs all these.
http://opencv.willowgarage.com/documentation/camera_calibration_and_3d_reconstruction.html - this is the link to all the functions that i've mentioned.
So, the steps in order of coding are:
1> stereoCalibrate (use 2 views from same camera for now): get distortion coeffs, intrinsic matrices for both cameras and R & T. (Which you have already performed).
2> calculate the disparity and store the image - use the disparity calculation shown here (3d reconstruction from 2 images without info about the camera) to understand what kind of input is expected as the first & second argument to reprojectImageto3D.
3> use stereoRectify to get Q.
4> plug in all values into reprojectImage to3D to generate coords. Every entry in the output array _3dImage i.e. at each pixel we will have 3 values stored together: the x,y coordinate corresponding to the pixel and the z coordinate calculated from Q. This z coordinate is essentially what we want.
Once you compute the disparity map and get _3dImage using Q, each(i, j) of _3dImage has (x, y, z) values. I even ported it to PCL to view 3D Image and this is how it looks.
This is how Disparity Map looks like
and this is its corresponding 3D View using PCL
Here's my Setup: Kinect mounted on an actuator for horizontal movement.
Here's a short demo of what I am doing. http://www.youtube.com/watch?v=X1aSMvDQhDM
Here's my Scenario:
Please refer to above figure. Assume the distance between the center of the Actuator,'M', and the Center of the optic axis of Kinect, 'C', is 'dx'(millimeters), the depth information 'D'(millimeters) obtained from Kinect is relative to the optic axis. Since I now have a actuator mounted onto the Center of Kinect, the actual depth between object and Kinect is 'Z'.
X is the distance between optical axis and object, in pixels. Theta2 is the angle between optic axis and object. 'dy' can be ignored.
Here's my Problem.
To obtain Z, I can simply use the distance equation in Figure 2. However I do not know the real world value of X in mm. If I have the angle between the object and optical axis 'theta2', I could use Dsin(theta2) to obtain X in mm. However theta2 is also unknown. Since if X (in mm) is know, I can get theta2, if theta2 is known, I can get X. So how should I obtain either the X value in mm or the angle between optic axis and Object P?
Here's what I've tried:
Since I know the max field of view for Kinect is 57degrees, and the max horizontal resolution of Kinect is 640pixels, I can say that 1 degree for kinect covers 11.228 (640/57) pixels. However, through experiments I discover that this results in error of at least 2 degrees. I suspect its due to lens distortion on the Kinect. But I don't know how to compensate/normalize it.
Any ideas/helps are greatly appreciated.
I am using OpenCV for an optical measurement system. I need to carry out a perspective transformation between two images, captured by a digital camera. In the field of view of the camera I placed a set of markers (which lie in a common plane), which I use as corresponding points in both images. Using the markers' positions I can calculate the homography matrix. The problem is, that the measured object, whose images I actually want to transform is positioned in a small distance from the markers and in parallel to the markers' plane. I can measure this distance.
My question is, how to take that distance into account when calculating the homography matrix, which is necessary to perform the perspective transformation.
In my solution it is a strong requirement not to use the measured object points for calculation of homography (and that is why I need other markers in the field of view).
Please let me know if the description is not precise.
Presented in the figure is the exemplary image.
The red rectangle is the measured object. It is physically placed in a small distance behind the circular markers.
I capture images of the object from different camera's positions. The measured object can deform between each acquisition. Using circular markers, I want to transform the object's image to the same coordinates. I can measure the distance between object and markers but I do not know, how should I modify the homography matrix in order to work on the measured object (instead of the markers).
This question is quite old, but it is interesting and it might be useful to someone.
First, here is how I understood the problem presented in the question:
You have two images I1 and I2 acquired by the same digital camera at two different positions. These images both show a set of markers which all lie in a common plane pm. There is also a measured object, whose visible surface lies in a plane po parallel to the marker's plane but with a small offset. You computed the homography Hm12 mapping the markers positions in I1 to the corresponding markers positions in I2 and you measured the offset dm-o between the planes po and pm. From that, you would like to calculate the homography Ho12 mapping points on the measured object in I1 to the corresponding points in I2.
A few remarks on this problem:
First, notice that an homography is a relation between image points, whereas the distance between the markers' plane and the object's plane is a distance in world coordinates. Using the latter to infer something about the former requires to have a metric estimation of the camera poses, i.e. you need to determine the euclidian and up-to-scale relative position & orientation of the camera for each of the two images. The euclidian requirement implies that the digital camera must be calibrated, which should not be a problem for an "optical measurement system". The up-to-scale requirement implies that the true 3D distance between two given 3D points must be known. For instance, you need to know the true distance l0 between two arbitrary markers.
Since we only need the relative pose of the camera for each image, we may choose to use a 3D coordinate system centered and aligned with the coordinate system of the camera for I1. Hence, we will denote the projection matrix for I1 by P1 = K1 * [ I | 0 ]. Then, we denote the projection matrix for I2 (in the same 3D coordinate system) by P2 = K2 * [ R2 | t2 ]. We will also denote by D1 and D2 the coefficients modeling lens distortion respectively for I1 and I2.
As a single digital camera acquired both I1 and I2, you may assume that K1 = K2 = K and D1 = D2 = D. However, if I1 and I2 were acquired with a long delay between the acquisitions (or with a different zoom, etc), it will be more accurate to consider that two different camera matrices and two sets of distortion coefficients are involved.
Here is how you could approach such a problem:
The steps in order to estimate P1 and P2 are as follows:
Estimate K1, K2 and D1, D2 via calibration of the digital camera
Use D1 and D2 to correct images I1 and I2 for lens distortion, then determine the marker positions in the corrected images
Compute the fundamental matrix F12 (mapping points in I1 to epilines in I2) from the corresponding markers positions and infer the essential matrix E12 = K2T * F12 * K1
Infer R2 and t2 from E12 and one point correspondence (see this answer to a related question). At this point, you have an affine estimation of the camera poses, but not an up-to-scale one since t2 has unit norm.
Use the measured distance l0 between two arbitrary markers to infer the correct norm for t2.
For the best accuracy, you may refine P1 and P2 using a bundle adjustment, with K1 and ||t2|| fixed, based on the corresponding marker positions in I1 and I2.
At this point, you have an accurate metric estimation of the camera poses P1 = K1 * [ I | 0 ] and P2 = K2 * [ R2 | t2 ]. Now, the steps to estimate Ho12 are as follows:
Use D1 and D2 to correct images I1 and I2 for lens distortion, then determine the marker positions in the corrected images (same as 2. above, no need to re-do that) and estimate Hm12 from these corresponding positions
Compute the 3x1 vector v describing the markers' plane pm by solving this linear equation: Z * Hm12 = K2 * ( R2 - t2 * vT ) * K1-1 (see HZ00 chapter 13, result 13.5 and equation 13.2 for a reference on that), where Z is a scaling factor. Infer the distance to origin dm = ||v|| and the normal n = v / ||v||, which describe the markers' plane pm in 3D.
Since the object plane po is parallel to pm, they have the same normal n. Hence, you can infer the distance to origin do for po from the distance to origin dm for pm and from the measured plane offset dm-o, as follows: do = dm ± dm-o (the sign depends of the relative position of the planes: positive if pm is closer to the camera for I1 than po, negative otherwise).
From n and do describing the object plane in 3D, infer the homography Ho12 = K2 * ( R2 - t2 * nT / do ) * K1-1 (see HZ00 chapter 13, equation 13.2)
The homography Ho12 maps points on the measured object in I1 to the corresponding points in I2, where both I1 and I2 are assumed to be corrected for lens distortion. If you need to map points from and to the original distorted image, don't forget to use the distortion coefficients D1 and D2 to transform the input and output points of Ho12.
The reference I used:
[HZ00] "Multiple view geometry for computer vision", by R.Hartley and A.Zisserman, 2000.
In my project my users can choose to be put in a random position inside a given, circular area.
I have the latitude and longitude of the center and the radius: how can I calculate the latitude and longitude of a random point inside the given area?
(I use PHP but examples in any language will fit anyway)
You need two randomly generated numbers.
Thinking about this using rectangular (Cartesian) (x,y) coordinates is somewhat unnatural for the problem space. Given a radius, it's somewhat difficult to think about how to directly compute an (Δx,Δy) delta that falls within the circle defined by the center and radius.
Better to use polar coordinates to analyze the problem - in which the dimensions are (r1, Θ). Compute one random distance, bounded by the radius. Compute a random angle, from 0 to 360 degrees. Then convert the (r,Θ) to Cartesian (Δx,Δy), where the Cartesian quantities are simply offsets from your circle center, using the simple trigonometry relations.
Δx = r * cos(Θ)
Δy = r * sin(Θ)
Then your new point is simply
xnew = x + Δx
ynew = y + Δy
This works for small r, in which case the geometry of the earth can be approximated by Euclidean (flat plane) geometry.
As r becomes larger, the curvature of the earth means that the Euclidean approximation does not match the reality of the situation. In that case you will need to use the formulas for geodesic distance, which take into account the 3d curvature of the earth. This begins to make sense, let's say, above distances of 100 km. Of course it depends on the degree of accuracy you need, but I'm assuming you have quite a bit of wiggle room.
In 3d-geometry, you once again need to compute 2 quantities - the angle and the distance. The distance is again bound by your r radius, except in this case the distance is measured on the surface of the earth, and is known as a "great circle distance". Randomly generate a number less than or equal to your r, for the first quantity.
The great-circle geometry relation
d = R Δσ
...states that d, a great-circle distance, is proportional to the radius of the sphere and the central angle subtended by two points on the surface of the sphere. "central angle" refers to an angle described by three points, with the center of the sphere at the vertex, and the other two points on the surface of the sphere.
In your problem, this d must be a random quantity bound by your original 'r'. Calculating a d then gives you the central angle, in other words Δσ , since the R for the earth is known (about 6371.01 km).
That gives you the absolute (random) distance along the great circle, away from your original lat/long. Now you need the direction, quantified by an angle, describing the N/S/E/W direction of travel from your original point. Again, use a 0-360 degree random number, where zero represents due east, if you like.
The change in latitude can be calculated by d sin(Θ) , the change in longitude by d cos(Θ). That gives the great-circle distance in the same dimensions as r (presumably km), but you want lat/long degrees, so you'll need to convert. To get from latitudinal distance to degrees is easy: it's about 111.32 km per degree regardless of latitude. The conversion from longitudinal distance to longitudinal degrees is more complicated, because the longitudinal lines are closer to each other nearer the poles. So you need to use some more complex formulae to compute the change in longitude corresponding to the selected d (great distance) and angle. Remember you may need to hop over the +/- 180° barrier. (The designers of the F22 Raptor warplane forgot this, and their airplanes nearly crashed when attempting to cross the 180th meridian.)
Because of the error that may accumulate in successive approximations, you will want to check that the new point fits your constraints. Use the formula
Δσ = arccos( cos(Δlat) - cos(lat1)*cos(lat2)*(1 - cos(Δlong) ) .
where Δlat is the change in latitude, etc.
This gives you Δσ , the central angle between the new and old lat/long points. Verify that the central angle you've calcuated here is the same as the central angle you randomly selected previously. In other words verify that the computed d (great-circle-distance) between the calculated points is the same as the great circle distance you randomly selected. If the computed d varies from your selected d, you can use numerical approximation to improve the accuracy, altering the latitude or longitude slightly until it meets your criterion.
This can simply be done by calculating a random bearing (between 0 and 2*pi) and a random distance between 0 and your desired maximum radius. Then compute the new (random) lat/lon using the random bearing/range from your given lat/lon center point. See the section 'Destination point given distance and bearing from start point' at this web site: http://www.movable-type.co.uk/scripts/latlong.html
Note: the formula given expects all angles as radians (including lat/lon). The resulting lat/lon with be in radians also so you will need to convert to degrees.