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

Car*_*ote 7 c++ opencv bytearray

我需要使用OpenCV读取图像,获取其大小并将其发送到服务器,以便处理图像并将其提供给我提取的功能.

我一直在考虑使用a vector<byte>,但我不明白如何将数据复制到cv :: Mat.我想要快,所以我试图用指针访问数据,但我有一个运行时异常.我有类似的东西.

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

        }           
    }
Run Code Online (Sandbox Code Playgroud)
  • 这项任务的最佳方法是哪种?

Jav*_*ock 9

直接访问是一个好主意,因为它是OpenCV最快的,但你错过了这一步,这可能就是你的程序中断的原因.下一行错了:

v_char.push_back(*(uchar*)(image.data+ i + j)); 
Run Code Online (Sandbox Code Playgroud)

你不必增加i,你必须增加i + image.step.就是这样:

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

        }           
    }
Run Code Online (Sandbox Code Playgroud)


Dia*_*cus 6

改进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);
Run Code Online (Sandbox Code Playgroud)

编辑:构造函数初始化将分配足够的空间以避免额外的重新分配,但它也会将向量中的所有项目设置为默认值(0).以下代码避免了这种额外的初始化.

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);
}
Run Code Online (Sandbox Code Playgroud)

  • 因为一般情况下Mat :: step与Mat :: cols不同.这使您可以在不实际重新组织字节的情况下裁剪矩阵.您可以创建一个子矩阵,将一个窗口引用到另一个矩阵,而不复制数据.当您更改子矩阵中的单元格时,实际上会更改原始矩阵中的单元格,子矩阵仅参考该单元格. (3认同)

Sam*_*Sam 6

到目前为止,您已收到很好的答案,但这不是您的主要问题.将图像发送到服务器之前,您可能想要做的是压缩它.

因此,请看一下cv::imencode()如何压缩它,并将cv::imdecode()其转换回服务器中的OpenCV矩阵.只需将imencode ouptut推入插座即可.