Levenberg Marquardt in calibration opencv - c++

I tried to understand Levenberg-Marquardt algorithm implementation in OpenCv Camera Calibration.
In W.Burger's paper-> here
I saw this Matrix in page 24.
So what does theoretically mean of this matrix' each cell?
And how it implemented in openCv code.

Levenberg Marquardt is a classical algorithm for non-linear optimization. OpenCV indeed uses it for camera calibration. One should understand the algorithm in general before diving into its usage in OpenCV.
Specifically, the matrix that you've pointed out is the Jacobian, a generalization of one dimensional derivative to multidimensional function.

Related

Custom 3D (parallel) FFTW transformation possible?

I have a 3D array of real data that I'd like to transform with a either a DST or DCT along one axis and normal DFT's along the other two axes. The result should be a 3D complex array that holds this transformation's coefficients.
Do you know if the FFTW3 package offers such a routine - possibly in parallel - out of the box? FFTW3 provides such a routine for a simple 3D DFT in all three directions.
And if not, would you might have a hint on how to achieve it the best way in C/C++?
My naive idea: Assembly of DST/DCT followed by a 2D real-to-complex transformation along the first axis inside some wrapping routine. Then, one could think of a 1D decomposition to achieve the parallelism. A 2D would be nicer but much more work.
PS:
This transformation is used in a spectral method for solving the Navier-Stokes equation.
Your naive idea is the way to go. Individual dimensions can be transformed independently.

3D Convolution C/C++ Code for Small Kernels

I am looking for a fast C (or C++) code that does 3D convolution with small kernels. What I have found online so far are based on FFT and require the use of other libraries. However, as pointed out by many, these FFT-based convolution codes are not suitable for small kernels (in my case they are mainly 3×3×3 or 5×5×5). Is there a C/C++ code that directly implements 3D convolution algorithm? I can implement a 3D convolution in a code according to its definition. However, what I write will not be the most efficient and fast implementation. I am actually looking for a code that has been verified in this aspect.

Confusion about methods of pose estimation

I'm trying to do pose estimation (actually [Edit: 3DOF] rotation is all I need) from a planar marker with 4 corners = 4 coplanar points.
Up until today I was under the impression from everything I read that you will always compute a homography (e.g. using DLT) and decompose that matrix using the various methods available (Faugeras, Zhang, the analytic method which is also described in this post here on stackexchange) and refine it using non-linear optimization, if necessary.
First minor question: if this is an analytical method (simply taking two columns from a matrix and creating an orthonormal matrix out of these resulting in the desired rotation matrix), what is there to optimize? I've tried it in Matlab and the result jitters badly so I can clearly see the result is not perfect or even sufficient, but I also don't understand why one would want to use the rather expensive and complex SVDs used by Faugeras and Zhang if this simple method yields results already.
Then there are iterative pose estimation methods like the Ortohogonal Iteration (OI) Algorithm by Lu et al. or the Robust Pose Estimation Algorithm by Schweighofer and Pinz where there's not even a mention of the word 'homography'. All they need is an initial pose estimation which is then optimized (the reference implementation in Matlab done by Schweighofer uses the OI algorithm, for example, which itself uses some method based on SVD).
My problem is: everything I read so far was '4 points? Homography, homography, homography. Decomposition? Well, tricky, in general not unique, several methods.' Now this iterative world opens up and I just cannot connect these two worlds in my head, I don't fully understand their relation. I cannot even articulate properly what my problem is, I just hope someone understands where I am.
I'd be very thankful for a hint or two.
Edit: Is it correct to say: 4 points on a plane and their image are related by a homography, i.e. 8 parameters. Finding the parameters of the marker's pose can be done by calculating and decomposing the homography matrix using Faugeras, Zhang or a direct solution, each with their drawbacks. It can also be done using iterative methods like OI or Schweighofer's algorithm, which at no point calculate the homography matrix, but just use the corresponding points and which require an initial estimation (for which the initial guess from a homography decomposition could be used).
With only four points your solution will be normally very sensitive to small errors in their location, particularly when the rectangle is nearly orthogonal to the optical axis (this is because the vanishing points are not observable - they are outside the image and very far from the measurements - and the pose is given by the cross product of the vectors from the centre of the quadrangle to the vanishing points).
Is your pattern such that the corners can be confidently located with subpixel accuracy? I recommend using "checkerboard-type" patterns for the corners, which allow using a good and simple iterative refining algorithm to achieve subpixel accuracy (look up "iterative saddle points algorithm", or look up the docs in OpenCV).
I will not provide you with a full answer, but it looks like at least one of the points that need to be clarified is this:
homography is an invertible mapping from P^2 (homogeneous 3-vectors) to itself, which always may be represented by an invertible 3x3 matrix. Having said that, note that if your 3d points are coplanar you will always be able to use homography to relate the world points to the image points.
In general, a point in 3-space is represented in homogeneous coordinates as a 4-vector. Projective transformation acting on P^3 is represented by a non-singular 4x4 matrix (15 degrees of freedom, 16 elements minus one for overall scale).
So, the bottom line is that if your model is planar, you will be able to get away with a homography (8 DOF) and an appropriate algorithm, while in general case you will need to estimate 4x4 matrix and would need a different algorithm for that.
Hope this helps,
Alex

Matrix logarithm algorithm

is there any way to compute the matrix logarithm in OpenCV? I understand that it's not available as a library function, but, pointers to a good source (paper, textbook, etc) will be appreciated.
As a matter of fact, I'm in the process of programming the matrix logarithm in the Eigen library which is apparently used in some Willow Garage libraries; not sure about OpenCV. Higham's book (see answer by aix) is the best reference in my opinion and I'm implementing Algorithm 11.11 in his book. That is a rather complicated algorithm though.
Diagonalization (as in Alexandre's comment) is an easy-to-program method which works very well for symmetric positive definite matrices. It also works well for many general matrices. However, it is not accurate for matrices whose eigenvalues are close together, and it fails for matrices that are not diagonalizable.
If you want something more robust than diagonalization but less complicated than Higham's Algorithm 11.11 then I'd recommend to do a Schur decomposition followed by inverse scaling and squaring. This is Algorithm 11.10 in Higham's book, and described in the paper "Approximating the Logarithm of a Matrix to Specified Accuracy" (http://dx.doi.org/10.1137/S0895479899364015, preprint at http://eprints.ma.man.ac.uk/318/).
If you use OpenCV matrices, you can easily map them to Eigen3 matrices. See this post:
OpenCV CV::Mat and Eigen::Matrix
Then, Eigen3 library has a matrix logarithm function that you can use:
http://eigen.tuxfamily.org/dox/unsupported/group__MatrixFunctions__Module.html
it is under the unsupported module, but this is not an issue, this just means:
These modules are contributions from various users. They are provided
"as is", without any support.
-- http://eigen.tuxfamily.org/dox/unsupported/
Hope this is of help.

Convolution with separable kernel

I'm looking at the CUDA SDK convolution with separable kernels, and I have a simple question but can't find an answer:
Do the vectors, whose convolution gives the kernel, need to have the same size? Can I first perform a row-convolution with a vector 1x3 and then a column convolution with another one 5x1 ? Or they both need to be same size? Google isn't helping (or I'm unable to search for an answer)
Yes, the vectors can be different sizes. The only consequence is that you'll get a rectangular matrix that is not square.
The vectors of a separable convolution could only be different sizes if the equivalent convolution matrix was not square.