Ask Your Question

Revision history [back]

The answer can be found e.g. here: http://stackoverflow.com/questions/37898019/how-to-calculate-matrix-rank-in-opencv

From there, extracting: 1) first we compute the SVD

Mat s, u, vt;
SVD::compute(M, s, u, vt);

2) Now we have singular values in s and rotation matrices (you can ignore those) in u and vt. Next we could count the number of non-zero singular values, which is equal to the rank:

int rank = countNonZero(s);

However, due to limited numerical precision, some singular values will be nearly-zero and we might (and probably will) want to count them as zeros, working with some threshold:

int rank = countNonZero(s > thr);

In the link above, they recommend value of the threshold thr as 0.0001. I think that's a bit too high, but that depends on what your problem is and how different your singular values will be. I wouldn't go below 1e-16, but maybe something like thr = 1e-10 * s.at<double>(0,0) isn't a bad choice in my opinion, weighting by the largest singular value...