c++arraysopencvvectorsynthesis

Convert Mat to Array/Vector in OpenCV


I am novice in OpenCV. Recently, I have troubles finding OpenCV functions to convert from Mat to Array. I researched with .ptr and .at methods available in OpenCV APIs, but I could not get proper data. I would like to have direct conversion from Mat to Array(if available, if not to Vector). I need OpenCV functions because the code has to be undergo high level synthesis in Vivado HLS. Please help.


Solution

  • If the memory of the Mat mat is continuous (all its data is continuous), you can directly get its data to a 1D array:

    std::vector<uchar> array(mat.rows*mat.cols*mat.channels());
    if (mat.isContinuous())
        array = mat.data;
    

    Otherwise, you have to get its data row by row, e.g. to a 2D array:

    uchar **array = new uchar*[mat.rows];
    for (int i=0; i<mat.rows; ++i)
        array[i] = new uchar[mat.cols*mat.channels()];
    
    for (int i=0; i<mat.rows; ++i)
        array[i] = mat.ptr<uchar>(i);
    

    UPDATE: It will be easier if you're using std::vector, where you can do like this:

    std::vector<uchar> array;
    if (mat.isContinuous()) {
      // array.assign(mat.datastart, mat.dataend); // <- has problems for sub-matrix like mat = big_mat.row(i)
      array.assign(mat.data, mat.data + mat.total()*mat.channels());
    } else {
      for (int i = 0; i < mat.rows; ++i) {
        array.insert(array.end(), mat.ptr<uchar>(i), mat.ptr<uchar>(i)+mat.cols*mat.channels());
      }
    }
    

    p.s.: For cv::Mats of other types, like CV_32F, you should do like this:

    std::vector<float> array;
    if (mat.isContinuous()) {
      // array.assign((float*)mat.datastart, (float*)mat.dataend); // <- has problems for sub-matrix like mat = big_mat.row(i)
      array.assign((float*)mat.data, (float*)mat.data + mat.total()*mat.channels());
    } else {
      for (int i = 0; i < mat.rows; ++i) {
        array.insert(array.end(), mat.ptr<float>(i), mat.ptr<float>(i)+mat.cols*mat.channels());
      }
    }
    

    UPDATE2: For OpenCV Mat data continuity, it can be summarized as follows:

    Please check out this code snippet for demonstration.