Store a cv::Mat in a byte array for data transfer to a server Store a cv::Mat in a byte array for data transfer to a server arrays arrays

Store a cv::Mat in a byte array for data transfer to a server


Direct access is a good idea as it is the fastest for OpenCV, but you are missing the step and that is probably the reason why your program breaks. The next line is wrong:

v_char.push_back(*(uchar*)(image.data+ i + j)); 

You don't have to increment i, you have to increment i + image.step. It will be this way:

Mat image = imread((path + "name.jpg"), 0);vector<byte> v_char;for(int i = 0; i < image.rows; i++)    {           for(int j = 0; j < image.cols; j++)        {            v_char.push_back(*(uchar*)(image.data+ i*image.step + j));                     }               }


You have received great answers so far, but this is not your main problem. What you probably want to do before sending an image to a server is to compress it.

So, take a look at cv::imencode() on how to compress it, and cv::imdecode() to transform it back to an OpenCV matrix in the server. just push the imencode ouptut to a socket and you're done.


Improving on Jav_Rock's answer here's how I would do it.

Mat image = ...;vector<byte> v_char(image.rows * image.cols);for (int i = 0; i < image.rows; i++)  memcpy(&v_char[i * image.cols], image.data + i * image.step, image.cols);

EDIT: Initialization by constructor will allocate enough space to avoid extra reallocation, but it will also set all items in the vector to default value (0). The following code avoids this extra initialization.

Mat image = ...;vector<byte> v_char;v_char.reserve(image.rows * image.cols);for (int i = 0; i < image.rows; i++){  int segment_start = image.data + i * image.step;  v_char.insert(v_char.end(), segment_start, segment_start + image.cols);}