1 | initial version |
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...