Expectation maximization in opencv - c++

My problem is this: I have to approximate a distribution with a mixture of two-component Gaussian model.
In particular I need to two variances of the two Gaussian distributions.
In openCv I can use the class EM; problem is that I can obtain only two covariance matrices but not the variances.
Is there a solution in order to find variance values?

In 2D case you can imagine variance as radius of circle. Covariavce matrix defines ellipse semiaxes (eigen vectors (directions), and eigenvalues(lengths)), so the problem is can you transform ellipse to circle? If yes, then you should decide which way you'll do it. You can get as radius long or short axis of ellipse, or you can find average.

Related

How to get the Gaussian matrix with variance σs in opencv?

I'm trying to design a line detector in opencv, and to do that, I need to get the Gaussian matrix with variance σs.
The final formula should be
H=Gσs∗(Gσd')T, and H is the detector that I'm going to create, but I have no idea how am I supposed to create the matrix with the variance and furthermore calculate H finally.
Update
This is the full formula.where “T” is the transpose operation.Gσd' is the first-order derivative of a 1-D Gaussian function Gσd with varianceσd in this direction
****Update****
These are the two formulas that I want, I need H for further use so please tell me how to generate the matrix. thx!
As a Gaussian filter is quite common, OpenCV has a built-in operation for it: GaussianBlur.
When you use that function you can set the ksize argument to 0/0 to automatically compute the pixel size of the kernel from the given sigmas.
A Gaussian 2D filter kernel is separable. That means you can first apply a 1D filter along the x axis and then a 1D filter along the y axis. That is the reason for having two 1D filters in the equation above. It is much faster to do two 1D filter operations instead of one 2D.

OpenCV gaussian curve fitting

I'm looking for fitting a Gaussian curve using OpenCV.
I can have 1D or 2D Mat, and I'd like to calculate the Gaussian parameters of the best Gaussian fit over the matrix.
However, I'd like to be able to fix some parameter (e.g. the Gaussian mean or variance).
The 1D model I'd like to fit is the following:
y = a + (b - a) * exp( -( x - c )/( 2 * d^2 ) )
In the case of 2D Mat, the model is the same of a multi-variate Gaussian function.
Has OpenCV some implementation suitable for my fitting needs?
If yes, can you provide an example or some useful links?
Thank you in advance.
Fitting a Gaussian curve simply means calculating its parameters which in 1D case are scalar mean and variance. Mean = sum(Xi)/n, variance = sum(Xi-mean)^2/(n-1), where ^2 means squared. This gets more interesting for 2D case. Mean is still calculated in the same way but it becomes a 2D vector. Instead of variance you calculate a covariance matrix like this. It is 2x2 matrix.
There's nothing to do that in OpenCV. However, if you derive the equations (Hessian matrix, etc.) you can easily implement some Levenberg-Marquardt estimation procedure with the cv::Mat matrix type.

Fit a circle or a spline into a bunch of 3D Points

I have some 3D Points that roughly, but clearly form a segment of a circle. I now have to determine the circle that fits best all the points. I think there has to be some sort of least squares best fit but I cant figure out how to start.
The points are sorted the way they would be situated on the circle. I also have an estimated curvature at each point.
I need the radius and the plane of the circle.
I have to work in c/c++ or use an extern script.
You could use a Principal Component Analysis (PCA) to map your coordinates from three dimensions down to two dimensions.
Compute the PCA and project your data onto the first to principal components. You can then use any 2D algorithm to find the centre of the circle and its radius. Once these have been found/fitted, you can project the centre back into 3D coordinates.
Since your data is noisy, there will still be some data in the third dimension you squeezed out, but bear in mind that the PCA chooses this dimension such as to minimize the amount of data lost, i.e. by maximizing the amount of data that is represented in the first two components, so you should be safe.
A good algorithm for such data fitting is RANSAC (Random sample consensus). You can find a good description in the link so this is just a short outline of the important parts:
In your special case the model would be the 3D circle. To build this up pick three random non-colinear points from your set, compute the hyperplane they are embedded in (cross product), project the random points to the plane and then apply the usual 2D circle fitting. With this you get the circle center, radius and the hyperplane equation. Now it's easy to check the support by each of the remaining points. The support may be expressed as the distance from the circle that consists of two parts: The orthogonal distance from the plane and the distance from the circle boundary inside the plane.
Edit:
The reason because i would prefer RANSAC over ordinary Least-Squares(LS) is its superior stability in the case of heavy outliers. The following image is showing an example comparision of LS vs. RANSAC. While the ideal model line is created by RANSAC the dashed line is created by LS.
The arguably easiest algorithm is called Least-Square Curve Fitting.
You may want to check the math,
or look at similar questions, such as polynomial least squares for image curve fitting
However I'd rather use a library for doing it.

General formula to generate a cubic bezier elliptical arc?

How could I implement in C a simple way to generate the 2 missing control points for an elliptic arc given a start and end point? I don't need fancy error estimation, just something that can take points A and D and generate the control points B and C for the elliptical arc where I can then use the cubic bezier interpolation algorithm to generate the curve.
something like
void GetArcControlPoints(Point a, Point &b, Point &c, Point d)
{
.....
b = ...
c = ....
}
Thanks
There are some flaws in the math behind your question:
Bézier curves are polynomial functions of a parameter t in the unit interval [0;1]. Ellipses are defined using the trigonometrical functions, which are transcendental, thus, not algebraic, thus, not polynomial. You cannot generate an ellipse arc using Bézier curves (neither cubic nor of any degree n). But let's suppose you just want to approximate an ellipse arc. Since you have not specified how good the approximation has to be, there is no way to ensure the Bézier curve will be "ellipse enough" for you. In fewer terms: You need an error parameter.
There are infinite ellipse arcs passing through two given points. Thus, the two points give not enough information to specify an ellipse, an arc of which which could then be approximated using a Bézier curve. To make things worse, since you want an ellipse arc, not the whole ellipse, you also have to specify how much of the ellipse has to be "covered" by the arc, in percentage (100% = the whole ellipse), radians (2*pi = the whole ellipse), whatever. In fewer terms: You need even more (input) parameters, just to specify a single arc of a single ellipse.
Until the math is done right, you cannot go to the next step (coding).
EDIT:
Since you need a whole ellipse, I would recommend using two or four Bézier patches instead of a single Bézier curve.
You can think of the ellipse as a circle that was "stretched" on one of the dimensions. Now, since "stretch" transforms are linear and Bézier functions are linear on the control points, you can calculate the control points for a Bézier curve approximating a 90 degree circle arc, then apply the "stretch" transform to the control points, and voilà, you get the control points for a Bézier curve approximating a "90 degree" ellipse arc. Getting the whole ellipse is just repeating the procedure four times.
Here is a derivation for the control points of a unit circle segment:
http://www.whizkidtech.redprince.net/bezier/circle/kappa/
Every possible ellipse can be generated by applying the appropriate affine transformation.
The kappa formula is just an approximation. This one is a good approximation for drawing a circle or ellipse with 4 cubic Bezier: it matches exactly on 8 points (those on the two axis and on the two main diagonals, the only points considered in the kappa formula), but there are differences everywhere else.
However, even if we can't use such splines to draw circles or ellipses with Beziers, there does exist an "exact" approximation (up to 1 half-pixel of difference) using only arithmetic operations to draw a circle incrementally pixel by pixel, based on the Bresenham algorithm (such approximation is possible because we can compute exactly, using only additions, the square distance of points to the center of the circle or the sum of distances to the two focal points of an ellipse and check if a pixel is "inside" or "outside" of it, and because we know the exact position of a starting point on the circle or ellipse, so we can just test which one of the two possible neighbours, in any one of the 8 sectors, are best approximating the circle or ellipse).
Such incremental algorithm approximating of elliptic arcs is completely different from those used to for Bezier splines but it is very efficient too (and in fact even faster than when drawing arbitrary Beziers splines).

develop distance matrix using coordinates

hey, I have been given a problem, I basically have been given a piece of grid paper of arbitary size and have to develop a distance matrix using only the coordinates for each of the grid points on the page.
I'm thinking the best approach would be something like the Floyd-Warshall or Djikstra algorithms for shortest path pair, but don't know how to adapt it to coordinate distances, as all the documentation uses a pre-determined distance matrix. so any help would be grand
the distance matrix contains simply the distances to all other points.
Basically, you just have to calculate the distances using an appropriate metric. If you want the "normal" distance, it's sqrt((x1-x2)^2+(y1-y2)^2) where (x/y) are the coordinates of a point in mm / inches. If you want the distance on the paper just following the lines its |x1-x2|+|y1-y2|.
Graph algorithms would be a overkill unless you have walls on the paper.