简体   繁体   English

将cv :: Mat存储在字节数组中,以便将数据传输到服务器

[英]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. 我需要使用OpenCV读取图像,获取其大小并将其发送到服务器,以便处理图像并将其提供给我提取的功能。

I have been thinking of using a vector<byte> , but I don't understand how to copy the data to a cv::Mat. 我一直在考虑使用vector<byte> ,但我不明白如何将数据复制到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? 这项任务的最佳方法是哪种?

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. 直接访问是一个好主意,因为它是OpenCV最快的,但你错过了这一步 ,这可能就是你的程序中断的原因。 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 . 你不必增加i ,你必须增加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));             

        }           
    }

Improving on Jav_Rock's answer here's how I would do it. 改进Jav_Rock的答案就是我将如何做到这一点。

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). 编辑:构造函数的初始化将分配足够的空间以避免额外的重新分配,但它也会将向量中的所有项目设置为默认值(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);
}

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. 所以,看看cv::imencode()如何压缩它,然后看cv::imdecode()将它转换回服务器中的OpenCV矩阵。 just push the imencode ouptut to a socket and you're done. 只需将imencode ouptut推入插座即可。

I don't understand completely why you need to use a vector, but if it's really necessary I recommend you to do a simple memcpy: 我完全不明白为什么你需要使用一个向量,但如果真的有必要,我建议你做一个简单的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)); 

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM