h is a 3 x 3 homography matrix and v a simple 3 value “vector”. I want to multiply an image point (x_val, y_val,1) by the homography mat.
When I try to multiply h * v this line gives an exception from the following code:
Mat result = h * v;
However when I plug in the same values on a matrix calculator, I get a valid appearing result. Why a numerical result with the calculator but an exception with the code?
code:
#include "pch.h"
#include <iostream>
#include "opencv2/opencv.hpp"
using namespace cv;
using namespace std;
int main(int argc, char** argv)
{
mat h = [3.173213988149968, 2.743835115137366, -859.0011226922862;
-1.174647218292675, 8.585603304611913, -295.477168455984;
-0.000925351979118807, 0.003491582882384472, 1] ;
int x_val = 0;
int y_val = 0;
std::cin >> x_val;
std::cin >> y_val;
std::cout << "Test Output:" << std::endl;
std::cout << h << std::endl;
cv::Mat v({ x_val, y_val, 1 });
v = v.t();
std::cout << v << std::endl;
Mat result = h * v; **//exception**
return 0;
}
matrix multiplication site:
v = [1, 3, 5]
h = [3.173213988149968, 2.743835115137366, -859.0011226922862;
-1.174647218292675, 8.585603304611913, -295.477168455984;
-0.000925351979118807, 0.003491582882384472, 1]
Unhandled exception at 0x00007FFA778EA388 in findHomogtraphyPerspCorrect.exe: Microsoft C++ exception: cv::Exception at memory location 0x0000008EC3FCEA50.
Is there a better way to create a type Mat for v that stores 3 float or double values?
try typed Mat’s, they have a handy << operator to fill them:
Mat_<double> h(3,3);
h << 3.173213988149968, 2.743835115137366, -859.0011226922862,
-1.174647218292675, 8.585603304611913, -295.477168455984,
-0.000925351979118807, 0.003491582882384472, 1;
Mat_<double> v(1,3);
v << 1,3,5;
Mat result = v * h;
cout << result << endl;
I am confused. If I want to calculate the result of a homography and a test point, don’t I use matrix multiplication instead of dot product (referring to crackwitz post )?
Very handy. Code at least creates values instead of exceptions, notably with using transposition of v into a column vector. Working code below, assumes values of h.
std::cout << "Input sample vector values x, y:" << std::endl;
int x_val = 0;
int y_val = 0;
std::cin >> x_val;
std::cin >> y_val;
Mat_<double> v(1, 3);
v << x_val, y_val, 1;
v = v.t();
std::cout << "Test Output:" << std::endl;
std::cout << "h is:" << h << std::endl;
std::cout << "v is:" << v << std::endl;
Mat result_point = h * v;
std::cout << "result is:" << result_point << std::endl;
Input sample vector values x, y:
162
190
Test Output:
h is:[2.944066776924357, 2.048579798943197, -673.0627329845232;
-1.308294943749788, 7.159280664408568, -55.96595037151948;
-0.001110508324382617, 0.002920211750598963, 0.9999999999999999]
v is:[162;
190;
1]
result is:[193.10624667643;
1092.353594978643;
1.374937884063819]
that’s the same. matrix multiplication is just the dot product continued, and the dot product is a special case of matrix multiplication where the “matrices” are vectors and it doesn’t matter if they’re row or column vectors.
perhaps I’m being sloppy with the math. everyone else is. numpy is. it’s all implicit. I regularly curse mathematicians for their sloppiness. any compiler would throw the chalk they leave on the blackboard back at their faces.
say you multiply H with some vector v = \begin{pmatrix}x \\ y \\ 1\end{pmatrix} which represents the 2D point v = \begin{pmatrix}x \\ y\end{pmatrix}.
the result is another 3x1 vector… but since it’s supposed to be a 2D coordinate, you’d want the third coordinate to be 1, right? except, when multiplying with a homography, which can do projection, the last coordinate may not be 1… so you have to divide by it.
this 3-dimensional space is a projective space. all \begin{pmatrix}x \\ y \\ 1\end{pmatrix} \cdot w, for any w (that isn’t 0 because that’s a headache), represent the same \begin{pmatrix}x \\ y \end{pmatrix} point in real space.