1

I have this Mat:

Mat testDataMat(386, 2, CV_32FC1, testDataFloat);

Which takes in from:

float testDataFloat[386][2];

But I can't figure out how to turn it into a 1 Dimensional Array.

Any help?

MLMLTL
  • 1,519
  • 5
  • 21
  • 35
  • `float* testData1D = testDataFloat;` – Micka Jan 16 '15 at 10:18
  • a value of type "float (*)[2]" cannot be used to initialize an entity of type "float *" – MLMLTL Jan 16 '15 at 10:20
  • sorry, `float* testData1D = (float*)testDataFloat;` – Micka Jan 16 '15 at 10:40
  • wait, do you want to convert the whole 2D array to a 1D array,or only a single column? – Micka Jan 16 '15 at 11:09
  • I want to give Detected Features to an SVM to predict with – MLMLTL Jan 16 '15 at 11:31
  • so you want to use all `386*2` feature values, my code should be ok. But you have to make sure that the ordering is the same as during training (row- or column-first compared to your 2D array). I can't tell you how data was trained in your task =) – Micka Jan 16 '15 at 11:37

1 Answers1

1

sample includes:

  1. direct method to convert from float 2d array to float 1d array.
  2. way to create a cv::Mat from 2D float array
  3. way to create 1D float array from a 2D cv::Mat that has no padding (e.g. stepsize = size of a single row)

This one works for me:

int main()
{
    const int width = 2;
    const int height = 386;
    float testDataFloat[height][width];

    // create/initialize testdata
    for(unsigned int j=0; j<height; ++j)
        for(unsigned int i=0; i<width; ++i)
        {
            if(j%5 == 0)
                testDataFloat[j][i] = 0.0f;
            else
                testDataFloat[j][i] = 1.0f;
        }

    // -----------------------------------------------------------
    // Direct convert from 2D array to 1D array:
    float * testData1DDirect = (float*)testDataFloat;



    // -----------------------------------------------------------
    // create Mat with 2D array as input:
    cv::Mat testDataMat(height, width, CV_32FC1, testDataFloat);

    // convert from Mat to 1D array
    // this works only if there is no padding in the matrix.
    float * testData1D = (float*)testDataMat.data;


    // test whether the arrays are correct
    for(unsigned int i=0; i<width*height; ++i)
    {
        if(testData1D[i] != testData1DDirect[i])
            std::cout << "ERROR at position: " << i << std::endl;
    }

    // output the Mat as an image:
    cv::imshow("test", testDataMat);
    cv::waitKey(0);

}
Micka
  • 19,585
  • 4
  • 56
  • 74
  • To feed a `Mat` the 1D array, would this be correct? `Mat testDataMat1D(height, 0, CV_32FC1, testData1D);` – MLMLTL Jan 16 '15 at 11:01
  • 1
    the 1D array has size `width*height` elements (after conversion, alternatively use `arraySize`), and you can't use `0 cols` in a matrix, so the call should be: `Mat testDataMat1D(height*width, 1, CV_32FC1, testData1D);` ... but you could use the 2D array directly to feed it into the cv::Mat... – Micka Jan 16 '15 at 11:08
  • Yeah I meant 1 and not 0, but I didn't think of `height*width` thanks! Anyway, should `testDataMat1D` be legible to be feed into a `SVM.predict`? – MLMLTL Jan 16 '15 at 11:25
  • it is similar to http://stackoverflow.com/questions/14694810/using-opencv-and-svm-with-images and the way I read that, I would say it should be ok for `SVM.predict`, although I dont have any own experience with SVM. – Micka Jan 16 '15 at 11:35
  • @MLMLTL no, you cannot use a `Mat` with multiple rows to feed into `predict()`. It requires a single row, multi _column_ `Mat`. – a-Jays Jan 17 '15 at 11:14
  • so like `Mat exampleMat(1, x, CV_32FC1, exampleFloat);` or like `Mat exampleMat(x, 1, CV_32FC1, exampleFloat);` ? – MLMLTL Jan 19 '15 at 10:05