initialize an OpenCV Mat with an 2D array

前端 未结 4 1811
悲哀的现实
悲哀的现实 2020-12-03 03:09

In my application, I want to create a OpenCV Mat A (2-Dimensions) having some values and then pass it to another OpenCV function using A as input.

Currently, I\'m t

相关标签:
4条回答
  • 2020-12-03 03:35

    orginally, I used the mnemonic from OpenCV online guides:

    Mat::Mat(Size size, int type, void* data, size_t step=AUTO_STEP)
    

    But I didn't understand what the document means by "size_t step=AUTO_STEP". And this means that I can ommit 'step' argument with which OpenCV will automatically chooses AUTO_STEP

    I've tried and this works:

    A = Mat(2, 5, CV_32FC1, &data);
    

    for the 2D Mat initialized from array

    0 讨论(0)
  • 2020-12-03 03:37

    While your answer is correct for your situation, it's good to know what step and AUTO_STEP mean

    Usually, images are stored in continuous blocks of memory. Each row follows after the previous one, so you can access the data by pointer with a simple

    data = dataPtr[currentCol + width * currentRow];
    

    Where width is the row width in bytes (not in pixels!)

    But this is not always the case - sometimes you access a submatrix, and the data is continuous on each row, but to go the next row you have to jump a sequence of bytes.

    This is where the step (also known as stride) comes in. It represents the distance, in bytes, between two consecutive rows. In continuous matrices, its value is sizeof(pixel)*rowWidth, but it may have custom values in special situations. When you pass AUTO_STEP to the Mat constructor, it knows that the data is continuous and calculates the step with the above formula. So now, the more correct approach to reading pixel values is

    data = dataPtr[currentCol + step * currentRow];
    

    Which is working for all kinds of images.

    Last, but not least, do not forget that step is measured in bytes, not pixels. So if you have a 3-channel uchar RGB image, step will be 3*number of pixels, and if you have a 3 channel int image, step = 3(channels)*(4=sizeof(int))*(number rows)

    0 讨论(0)
  • 2020-12-03 03:42

    In addition to the above answers, there is another option.

    For a smaller data, I would prefer the following:

    Mat A = (Mat_<float>(2, 5) << 1, 2, 3, 4, 5, 7, 8, 9, 10, 11);
    

    You can easily get the desired result without the need to define an additional variable 'data'.

    0 讨论(0)
  • 2020-12-03 03:42

    Since data is 2D array - all of data, &data, *data, data[0], &data[0], and &data[0][0] point to base of array. Any of the above representation could be chosen to correctly construct the Mat in place of X in

    A = Mat(2, 5, CV_32FC1, X );
    

    Have peace of mind since data is accepted by OpenCV as void*and data access by OpenCV is as in line. I prefer same syntax for constructing Mat from single or multi dimensional arrays.

    A = Mat(1, 10, CV_32FC1, data ); //for 1D array
    A = Mat(2, 5, CV_32FC1, data ); //for 2D array
    

    Back to the query - Note that, your construction of Mat even from 1D array is incorrect. The step parameter is mentioned as 2. It just happened to work, since OpenCV overrides the step parameter provided, if the number of rows is 1. For higher dimensional arrays, OpenCV throws debug assertion for incorrect step parameter, which you got.

    0 讨论(0)
提交回复
热议问题