Intrinsic Parameters of Camera - computer-vision

I'm trying to do triangulation for 3D reconstruction and I came across an interesting observation which I cannot justify.
I have 2 sets of images. I know the correspondences and I'm finding the intrinsic and extrinsic parameters using a direct linear transformation. While I'm able to properly reconstruct the original scene, the intrinsic parameters are different even though the pictures are taken from the same camera. How is it possible to have different intrinsic parameters if the camera is the same? Also, if the intrinsic parameters are different, how am I able to reconstruct the scene perfectly?
Thank you

You haven't specified what you mean by "different", so i'm just going to point two possible sources of differences that come to mind. Let's denote the matrix of intrinsic parameters with K.
The first possible difference could just come from a scaling difference. If the second time you estimate your intrinsics matrix, you end up with a matrix
K_2=lambda*K
then it doesn't make any difference when projecting or reprojecting, since for any 3d point X you'll have
K_2*X=K*lambda*X //X is the same as lambda*X in projective geometry
The same thing happens when you backproject the point: you just obtain a direction, and then your estimation algorithm (e.g. least squares or a simpler geometric solution) takes care of estimating the depth.
The second reason for the difference you observe could just come from numerical imprecisions. Since you haven't given any information regarding the magnitude of the difference, I'm not sure if that is relevant to your case.

Related

Given 2 points with known speed direction and location, compute a path composed of (circle) arcs

So, I have two points, say A and B, each one has a known (x, y) coordinate and a speed vector in the same coordinate system. I want to write a function to generate a set of arcs (radius and angle) that lead A to status B.
The angle difference is known, since I can get it by subtracting speed unit vector. Say I move a certain distance with (radius=r, angle=theta) then I got into the exact same situation. Does it have a unique solution? I only need one solution, or even an approximation.
Of course I can solve it by giving a certain circle and a line(radius=infine), but that's not what I want to do. I think there's a library that has a function for this, since it's quite a common approach.
A biarc is a smooth curve consisting of two circular arcs. Given two points with tangents, it is almost always possible to construct a biarc passing through them (with correct tangents).
This is a very basic routine in geometric modelling, and it is indispensable for smoothly approximating an arbirtrary curve (bezier, NURBS, etc) with arcs. Approximation with arcs and lines is heavily used in CAM, because modellers use NURBS without a problem, but machine controllers usually understand only lines and arcs. So I strongly suggest reading on this topic.
In particular, here is a great article on biarcs on biarcs, I seriously advice reading it. It even contains some working code, and an interactive demo.

what kind of algorithm for generating height-map from contour line?

I'm looking for interpolating some contour lines to generating a 3D view. The contours are not stored in a picture, coordinates of each point of the contour are simply stored in a std::vector.
for convex contours :
, it seems (I didn't check by myself) that the height can be easily calculates (linear interpolation) by using the distance between the two closest points of the two closest contours.
my contours are not necessarily convex :
, so it's more tricky... actualy I don't have any idea what kind of algorithm I can use.
UPDATE : 26 Nov. 2013
I finished to write a Discrete Laplace example :
you can get the code here
What you have is basically the classical Dirichlet problem:
Given the values of a function on the boundary of a region of space, assign values to the function in the interior of the region so that it satisfies a specific equation (such as Laplace's equation, which essentially requires the function to have no arbitrary "bumps") everywhere in the interior.
There are many ways to calculate approximate solutions to the Dirichlet problem. A simple approach, which should be well suited to your problem, is to start by discretizing the system; that is, you take a finite grid of height values, assign fixed values to those points that lie on a contour line, and then solve a discretized version of Laplace's equation for the remaining points.
Now, what Laplace's equation actually specifies, in plain terms, is that every point should have a value equal to the average of its neighbors. In the mathematical formulation of the equation, we require this to hold true in the limit as the radius of the neighborhood tends towards zero, but since we're actually working on a finite lattice, we just need to pick a suitable fixed neighborhood. A few reasonable choices of neighborhoods include:
the four orthogonally adjacent points surrounding the center point (a.k.a. the von Neumann neighborhood),
the eight orthogonally and diagonally adjacent grid points (a.k.a. the Moore neigborhood), or
the eight orthogonally and diagonally adjacent grid points, weighted so that the orthogonally adjacent points are counted twice (essentially the sum or average of the above two choices).
(Out of the choices above, the last one generally produces the nicest results, since it most closely approximates a Gaussian kernel, but the first two are often almost as good, and may be faster to calculate.)
Once you've picked a neighborhood and defined the fixed boundary points, it's time to compute the solution. For this, you basically have two choices:
Define a system of linear equations, one per each (unconstrained) grid point, stating that the value at each point is the average of its neighbors, and solve it. This is generally the most efficient approach, if you have access to a good sparse linear system solver, but writing one from scratch may be challenging.
Use an iterative method, where you first assign an arbitrary initial guess to each unconstrained grid point (e.g. using linear interpolation, as you suggest) and then loop over the grid, replacing the value at each point with the average of its neighbors. Then keep repeating this until the values stop changing (much).
You can generate the Constrained Delaunay Triangulation of the vertices and line segments describing the contours, then use the height defined at each vertex as a Z coordinate.
The resulting triangulation can then be rendered like any other triangle soup.
Despite the name, you can use TetGen to generate the triangulations, though it takes a bit of work to set up.

Preferred Representation of a 3D-Plane in C/C++

What is the preferred way of representing a fixed-dimensional plane (struct) in a 3D-graphics when C/C++ is the preferred language.
Should we
store the normalized plane normal vector and origo-distance as separate entities or should we
express them together in a non-normalized vector?
First alternative requires one extra float/double but is other hand more efficient in algorithms that operate on the normal because it is already precalculated. First alternative is also more numerically stable if we vary the normal and offset separately.
Sadly, C++ is not the best language to work with planes. We can at first think that using four floating point values is a good choice as it fits in a SIMD register in SSE and VMX. So we may have a class with a single 128bits member, first three values represent the plane normal and the last a distance ( juste like homogenous coordinate, a plane do not always needs a normalized normal if we only care about the sign of a distance test ).
But when we works with planes to categorize points, sphere, and other volumes, implementing a single plane to point distance function will result to sub-optimal algorithm because most of the time, we know we will test a lot of points against a small number of planes. There is room for optimization !
The problem here has a name, in fact, not the problem, but the way we may represent the information. It's Array Of Structures versus Structure of Arrays ( AOS vs SOA ).
A common exercice in a 3D engine is bounding volume frustum culling ! An usual frustum is made of 6 planes, the right representation is not a Frustum class with a std::array<Plane,6> member, but most likely, 8 SIMD registers layout as : { P0X, P1X, P2X, P3X }, { P4X, P5X, FREEPLANE1X, FREEPLANE2X }, ... and so on for Y, Z and D. Not C++, but much better for SIMD programing.
It may also be useful to prefer a SOA reprensation for points too.
Conclusion : The best representation depends on what algorithm and what kind of data set will go thought your planes.

Looking for C/C++ library calculating max of Gaussian curve using discrete values

I have some discrete values and assumption, that these values lie on a Gaussian curve.
There should be an algorithm for max-calculation using only 3 discrete values.
Do you know any library or code in C/C++ implementing this calculation?
Thank you!
P.S.:
The original task is auto-focus implementation. I move a (microscope) camera and capture the pictures in different positions. The position having most different colors should have best focus.
EDIT
This was long time ago :-(
I'just wanted to remove this question, but left it respecting the good answer.
You have three points that are supposed to be on a Gaussian curve; this means that they lie on the function:
If you take the logarithm of this function, you get:
which is just a simple 2nd grade polynomial, i.e. a parabola with a vertical axis of simmetry:
with
So, if you know the three coefficients of the parabola, you can derive the parameters of the Gaussian curve; incidentally, the only parameter of the Gaussian function that is of some interest to you is b, since it tells you where the center of the distribution, i.e. where is its maximum. It's immediate to find out that
All that remains to do is to fit the parabola (with the "original" x and the logarithm of your values). Now, if you had more points, a polynomial fit would be involved, but, since you have just three points, the situation is really simple: there's one and only one parabola that goes through three points.
You now just have to write the equation of the parabola for each of your points and solve the system:
(with , where the zs are the actual values read at the corresponding x)
This can be solved by hand (with some time), with some CAS or... looking on StackOverflow :) ; the solution thus is:
So using these last equations (remember: the ys are the logarithm of your "real" values) and the other relations you can easily write a simple algebraic formula to get the parameter b of your Gaussian curve, i.e. its maximum.
(I may have done some mess in the calculations, double-check them before using the results, anyhow the procedure should be correct)
(thanks at http://www.codecogs.com/latex/eqneditor.php for the LaTeX equations)

Why do we need a Unit Vector (in other words, why do we need to normalize vectors)?

I am reading a book on game AI.
One of the terms that is being used is to normalize a vector which is to turn a vector into a unit. To do so you must divide each dimension x, y and z by its magnitude.
We must turn vector into a unit before we do anything with it. Why?
And could anyone give some scenarios where we must use a unit vector?
Thanks!
You don't have to normalize vectors, but it makes a lot of equations a little simpler when you do. It could also make API's smaller: any form of standardization has the potential to reduce the number of functions necessary.
Here's a simple example. Suppose you want to find the angle between two vectors u and v. If they are unit vectors, the angle is just arccos(uv). If they're not unit vectors, the angle is arccos(uv/(|u| |v|)). In that case, you end up computing the norms of u and v anyway.
As John D. Cook says - mainly you're doing this because you care about the direction, not the vector itself. Depending on context, you more than likely don't want / need the magnitude information - just the direction itself. You normalize to strip away the magnitude so that it doesn't skew other calculations, which in turn simplifies many other things.
In terms of AI - imagine you take the vector V between P1(the AI bad guy) and P2 (your hero) as the direction for the bad guy to move. You want the bad guy to move at a speed N per beat - how do you calculate this? Well, we either normalize the vector each beat, multiply by N to figure out how far they moved, or we pre-normalize the direction in the first place, and just multiply the unit vector by N each time - otherwise the bad guy would move further if it were further away from the hero! If the hero doesn't change position, that's one less calculation to worry about.
In that context, it's not a big deal - but what if you have a hundred bad guys? Or a thousand? What if your AI needs to deal with combinations of bad guys? Suddenly it's a hundred or thousand normalizations you're saving per beat. Since this is a handful of multiplies and a square root for each, eventually you reach the point where not normalizing the data ahead of time means you're going to kill your AI processing rate.
More broadly - math for this is really common - people are doing here what they do for things like 3D rendering - if you didn't unitize, for instance, the normals for your surfaces, you'd have potentially thousands of normalizations per rendering which are completely unnecessary. You have two options: one - make each function perform the calculation, or two - pre-normalize the data.
From the framework designer's perspective: the latter is inherently faster - if we assume the former, even if your user thinks to normalize the data, they're going to have to go through the same normalization routine OR you're going to have provide two versions of each function, which is a headache. But at the point you're making people think about which version of the function to call, you may as well make them think enough to call the correct one, and only provide it in the first place, making them do the right thing for performance.
You are often normalizing a vector because you only care about the direction the vector points and not the magnitude.
A concrete scenario is Normal Mapping. By combining light striking the surface and vectors that are perpendicular to the surface you can give an illusion of depth. The vectors from the surface define the parallel direction and the magnitude to the vector would actual make calculations wrong.
We must we turn a vector into units
before we do anything with it.
This statement is incorrect. All vectors are not unit vectors.
The vectors that form the basis for a coordinate space have two very nice properties that make them easy to work with:
They're orthogonal
They're unit vectors - magnitude = 1
This lets you write any vector in a 3D space as a linear combination of unit vectors:
(source: equationsheet.com)
I can choose to turn this vector into a unit vector if I need to by dividing each component by the magnitude
(source: equationsheet.com)
If you don't know that coordinate spaces or basis vectors are, I'd recommend learning a little more about the mathematics of graphics before you go much further.
In addition to the answers already provided, I would mention two important aspects.
Trigonometry is defined on a unit circle
All trigonometric functions are defined over a unit circle. The number pi itself is defined over a unit circle.
When you normalize vectors, you can use all trigonometric functions directly, without any rounds of scaling. As mentioned earlier, the angle between two unit vectors is simply: acos(dot(u, v)), without further scaling.
Unit vectors allow us to separate magnitude from direction
A vector can be interpreted as a quantity carrying two types of information: magnitude and direction. Force, velocity, and acceleration are important examples.
If you wish to deal separately with the magnitude and direction, a representation of the form vector = magnitude * direction, where magnitude is a scalar and direction a unit vector, is often very convenient: Changes in magnitude entail scalar manipulations, and changes in direction do not modify the magnitude. The direction has to be a unit vector to ensure that the magnitude of vector is exactly equal to magnitude.