0

I'm trying to convert the result Mat of templateMatch with the following code (which was found at: this question):

void convertmatVec(const cv::Mat& m, std::vector<uchar>& v) {
    if (m.isContinuous()) {
        v.assign(m.datastart, m.dataend);
    }
    else {
        printf("failed to convert / not continuous");           
        return;
    }
}

and when I check the size of the output it's not the same as the product of result's columns and rows (which is the same when I try to convert another Mat that I created): result: result

another Mat created with:

cv::Mat test(result.size(),false);
test.setTo(cv::Scalar(255));

which is then converted shows that the size is the same as the product:

test

So my question is how can I get the result's data so I can process it futher because I'm assuming the size of the vector should be the same as the product which it clearly isn't.

EDIT1: Added templateMatching code

void matchTemplatenoRotation(cv::Mat src, cv::Mat templ) {
cv::Mat img_display, result;

src.copyTo(img_display);

int result_cols = src.cols - templ.cols + 1;
int result_rows = src.rows - templ.rows + 1;

result.create(result_rows, result_cols, CV_32FC1);

cv::matchTemplate(src, templ, result, CV_TM_SQDIFF_NORMED);
cv::normalize(result, result, 0, 1, cv::NORM_MINMAX, -1, cv::Mat());
cv::Point minLoc, maxLoc;
double minVal, maxVal;

cv::minMaxLoc(result, &minVal, &maxVal, &minLoc, &maxLoc, cv::Mat());
cv::Point matchLoc = minLoc;

//end of templatematching

EDIT2 follow up question:

How come when I create another Mat with following code:

cv::Mat test(cv::Size(result.cols, result.rows),true);
test.setTo(cv::Scalar(255));
//cv::imshow("test3", test);
std::vector<float> testVector;
convertmatVec(test, testVector);

the vector size is as following:

enter image description here

Community
  • 1
  • 1
Rok
  • 476
  • 1
  • 5
  • 12

2 Answers2

1

It looks like your const cv::Mat& m has four channels.

Another thing to consider: if this Mat is the result of a matchTemplate(), then you should be using a vector<float>, instead of vector<uchar>.

Berriel
  • 12,659
  • 4
  • 43
  • 67
1

You have 4 times the expected number of elements in your vector because your matrix is of type CV_32FC1. If you look at the type of m.datastart and m.dataend you will see that they are uchar* and not float* as you expect.

To correct this, change v.assign(m.datastart, m.dataend); to v.assign((float*)m.datastart, (float*)m.dataend);. And you will need to pass a vector of float instead of a vector<uchar>.

Of course, your conversion function will only work for float type matrices. you could add some tests to detect the type of the matrix inside the function.

To answer your follow up question, it appears that you have the inverse problem. You are passing a CV_8U type matrix to a function that expects a CV_32F type one. Use your old conversion function for 8-bit matrices and use the fix I suggested for 32-bit floating-values matrices. You can also add a test inside the conversion function to automatically choose the right conversion. I also advise you to read a bit on OpenCV Mat class to understand better what type of data is in your matrices.

Sunreef
  • 4,452
  • 21
  • 33