Search code examples
c++arraysopencvmat

cv::Mat initialization using array


I experienced a strange behavior after for example initializing through

#include <iostream>
#include <opencv2/opencv.hpp>

int main() {
    cv::Mat h = cv::Mat(2, 2, CV_32F, {1.0, 2.0, 1.0, 0.0});
    std::cout << h << std::endl;
    return 0;
}

cout prints out [1, 1; 1, 1]. WTF just happened? I'm using eclipse on ubuntu, gcc version 5.4, OpenCV 3.2


Solution

  • You're not using a valid Mat constructor. You have a few options:

    1. From an array:

      float pf[] = { 1.f, 2.f, 3.f, 4.f };
      Mat1f m1(2, 2, pf);
      

      or

      std::vector<float> vf = { 1.f, 2.f, 3.f, 4.f };
      Mat1f m2(2, 2, vf.data());
      
    2. With comma initializers:

      Mat1f m3 = (Mat1f(2, 2) << 1.f, 2.f, 3.f, 4.f);
      
    3. If the matrix is small, you can use Matx:

      Matx22f m4(1.f, 2.f, 3.f, 4.f);
      

    Note that a Mat1f is a typedef for Mat_<float>, which is a Mat of type CV_32FC1.


    Using your method doesn't work because {1.0, 2.0, 1.0, 0.0} constructs cv::Scalar, so you call the constructor Mat(int rows, int cols, int type, cv::Scalar). Since you have only 1 channel, the matrix is initialized with the first value of this scalar, which is the first value in your initializer list.

    Note that this is just a coincidence since your matrix has 4 elements (the maximum number supported by Scalars). If you use a higher number of elements:

    cv::Mat h(2, 3, CV_32F, {3.f, 2.f, 1.f, 0.f, 2.f, 5.f});
    

    the code should not compile.