Question

A number of matrix expressions I have evaluate to a 1 by 1 matrix. I would like to do something like:

cv::Mat a = cv::Mat(n, m, CV_64F), b = ..., c = ...
double d = a.t() * b * c.inv(); // result happens to be 1 x 1 matrix

The way I found to do this is to write:

double d = ((cv::Mat)(a.t() * b * c.inv())).at<double>(0);

Which is a bit long and very confusing, especially if long expressions are involved.

Is there a better, clearer way to write this? can I somehow overload the operator double to apply only to 1x1 cv::MatExpr's?

Edit

A simple function to do this is of course possible, though ugly. Any more elegant solutions?

double toDouble(cv::MatExpr M) {
  cv::Mat A = M;
  if (A.rows != 1 || A.cols != 1) throw "Matrix is not 1 by 1!";
  return A.at<double>(0);
} 
Was it helpful?

Solution

What you could do is make use of the cv::Mat::dot function (documentation link), which takes two cv::Mat of same sizes and returns a double.

If the result of your operation is a 1x1 matrix, then you should be able to express it using cv::Mat::dot. For example, if a and b are nx1, the two following lines are equivalent:

double d = ((cv::Mat)(a.t() * b)).at<double>(0);

double d = a.dot(b);

One could also imagine more complex operations:

double d = (M.t()*U.inv()*a).dot(V.inv()*b);
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top