Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

I need to read an image with OpenCV, get its size and send it to a server so it processes the image and give it back to me the extracted features.

I have been thinking of using a vector<byte>, but I don't understand how to copy the data to a cv::Mat. I wan't it to be fast so I am trying to access the data with a pointer but I have a runtime exception. 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));             

        }           
    }
  • Which is the best approach for this task?
like image 442
Carlos Cachalote Avatar asked Oct 02 '12 14:10

Carlos Cachalote


2 Answers

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));             

        }           
    }
like image 198
Jav_Rock Avatar answered Sep 19 '22 01:09

Jav_Rock


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.

like image 44
Sam Avatar answered Sep 18 '22 01:09

Sam