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

I need to read the image from OpenCV, get its size and send it to the server so that it processes the image and returns the extracted functions to me.

I was thinking about using vector<byte> , but I don't understand how to copy data to cv :: Mat. I will not be fast, so I am trying to access data using a pointer, but I have an exception at runtime. I have something like this.

 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 + j)); } } 
  • What is the best approach for this task?
+6
source share
4 answers

Direct access is a good idea, as it is the fastest for OpenCV, but you are missing a step , and this is probably the reason your program crashes. The following line is incorrect:

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

You do not need to increase i , you need to increase i + image.step . It will be as follows:

 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)); } } 
+7
source

An improvement on Jav_Rock will answer here, 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 the constructor will allocate enough space to avoid additional redistribution, but it will also set all the elements in the default vector (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); } 
+5
source

So far you have received excellent answers, but this is not your main problem. You probably want to do before sending the image to the server to compress .

So, take a look at cv::imencode() on how to compress it, and cv::imdecode() to convert it back to the OpenCV matrix on the server. just click on the imencode icon on the socket and you're done.

+4
source

I do not understand why you need to use a vector, but if it is really necessary, I recommend that you make simple memcpy:

 vector<byte> v_char(image.width * image.height); //Allocating the vector with the same size of the matrix memcpy(v_char.data(), image.data, v_char.size() * sizeof(byte)); 
+1
source

Source: https://habr.com/ru/post/926762/


All Articles