3
votes

Matrix multiplication is a very basic task in image processing and OpenCV takes care of with a overloaded * operator. A STL vector of points can be converted into Mat by casting.

vector<Point2f> p1(2);
p1[0].x=1;p1[0].y=0;
p1[1].x=0;p1[1].y=1;
Mat p1M=Mat(p1);

As mentioned in OpenCV documentation, this will create matrix with a single column(with 2 elements) with rows equal to no of vectors:

[1 0;0 1]------>p1M.rows=2;p1M.cols=1

This creates a problem when you want to matrix multiply (p1M*p1M)...[2x1]*[2x1]???...Essentially i believe all the casting vector to Matrix does is to merge the vectors as it is....

However, the command p1M.at<float> (0,1) and p1M.at<float> (1,0) returns 0 and 1 resp. this made me think p1M*p1M is possible but unfortunately it only compiles and generates a run time error:

OpenCV Error: Assertion failed (a_size.width == len) in gemm, file /home/james/OpenCV-2.3.1/modules/core/src/matmul.cpp, line 708 terminate called after throwing an instance of 'cv::Exception' what(): /home/james/OpenCV-2.3.1/modules/core/src/matmul.cpp:708: error: (-215) a_size.width == len in function gemm

I am thinking of writing a function to just do that! vector to Mat and vice versa...Am i missing something?

1
From the assertion I would guess that the Matrix was not built from your vector in the form of 2x2. I would suggest you take a look into the Mat contrustor and look how the matrix is setup give a std:vector.boto
I think you are right that it will create a 2*1 matrix, but it creates a two channel 2*1 matrix. That means each element in the matrix is not a single float, but a cv::Vec2f. So if you print the following values: p1M.channels(), p1M.at<cv::Vec2f>(0, 0)[0], p1M.at<cv::Vec2f>(0, 0)[1], p1M.at<cv::Vec2f>(1, 0)[0], p1M.at<cv::Vec2f>(1, 0)[1], you should get 2, 1.0, 0.0, 0.0, 1.0. And I don't think OpenCV's matrix multiplication supports multi-channel matrix, that's why you got the error message.cxyzs7
I recommend ImageWatch (VS plugin) or a debugger, you can spot the type of the resulting Mat very easily like that. Or cout the number of channels.Ela782

1 Answers

2
votes

You might want to look into cv::Mat::reshape http://docs.opencv.org/modules/core/doc/basic_structures.html#mat-reshape

When you create a Mat from a list of points it creates one channel for each component of point. So if you use a Point3f it makes a single column Mat with 3 channels.

You could try converting p1M to the matrix you are expecting by calling

p1M.reshape(1);