代码之家  ›  专栏  ›  技术社区  ›  Richard Knop

如果图像文件的内容在char数组中,如何使用cv::imdecode?

  •  5
  • Richard Knop  · 技术社区  · 15 年前

    我在缓冲区jpeg buffer中有一个jpeg图像。我正在尝试将其传递给cv::imdecode函数:

    Mat matrixJprg = imdecode(Mat(jpegBuffer), 1);
    

    我得到这个错误:

    /home/richard/Desktop/richard/client/src/main.cc:108: error: no matching function for call to ‘cv::Mat::Mat(char*&)’
    

    这就是我如何填充jpegbuffer:

    FILE* pFile;
    long lSize;
    char * jpegBuffer;
    pFile = fopen ("img.jpg", "rb");
    if (pFile == NULL)
    {
        exit (1);
    }
    
    // obtain file size.
    fseek (pFile , 0 , SEEK_END);
    lSize = ftell (pFile);
    rewind (pFile);
    
    // allocate memory to contain the whole file.
    jpegBuffer = (char*) malloc (lSize);
    if (jpegBuffer == NULL)
    {
        exit (2);
    }
    
    // copy the file into the buffer.
    fread (jpegBuffer, 1, lSize, pFile);
    
    // terminate
    fclose (pFile);
    
    2 回复  |  直到 8 年前
        1
  •  14
  •   ronag    15 年前

    mat没有接受char*参数的构造函数。试试这个:

    std::ifstream file("img.jpg");
    std::vector<char> data;
    
    file >> std::noskipws;
    std::copy(std::istream_iterator<char>(file), std::istream_iterator<char>(), std::back_inserter(data));
    
    Mat matrixJprg = imdecode(Mat(data), 1);
    

    编辑:

    你也应该看看 LoadImageM .

    如果你的数据已经在char *缓冲区中,一种方法是将数据复制到STD::vector。

    std::vector<char> data(buf, buf + size);
    
        2
  •  8
  •   Programmer    8 年前

    我必须做同样的事情,我的图像数据已经在 char 数组格式,从网络和插件源到达。电流 answer 演示如何执行此操作 但它需要先将数据复制到向量中 这是浪费时间和资源。

    这可以在不创建副本的情况下直接执行。你和你的 imdecode(Mat(jpegBuffer), 1); 问题中的代码。

    您需要使用构造函数重载 Mat 下级:

    Mat(int rows, int cols, int type, void* data, size_t step=AUTO_STEP);
    

    创建这个 席子 通过 1 到行,数组的大小到列, CV_8UC1 将类型和char数组本身转换为数据参数。通过这个 席子 cv::imdecode 以mat作为第一个参数和 CV_LOAD_IMAGE_UNCHANGED 作为第二个参数。

    基本实例

    char *buffer = dataFromNetwork;
    int bufferLength = sizeOfDataFromNetwork;
    
    cv::Mat matImg;
    matImg = cv::imdecode(cv::Mat(1, bufferLength, CV_8UC1, buffer), CV_LOAD_IMAGE_UNCHANGED);
    

    imdecode

    int main() {
    
        //Open image file to read from
        char imgPath[] = "./test.jpg";
        ifstream fileImg(imgPath, ios::binary);
        fileImg.seekg(0, std::ios::end);
        int bufferLength = fileImg.tellg();
        fileImg.seekg(0, std::ios::beg);
    
        if (fileImg.fail())
        {
            cout << "Failed to read image" << endl;
            cin.get();
            return -1;
        }
    
        //Read image data into char array
        char *buffer = new char[bufferLength];
        fileImg.read(buffer, bufferLength);
    
        //Decode data into Mat 
        cv::Mat matImg;
        matImg = cv::imdecode(cv::Mat(1, bufferLength, CV_8UC1, buffer), CV_LOAD_IMAGE_UNCHANGED);
    
        //Create Window and display it
        namedWindow("Image from Char Array", CV_WINDOW_AUTOSIZE);
        if (!(matImg.empty()))
        {
            imshow("Image from Char Array", matImg);
        }
        waitKey(0);
    
        delete[] buffer;
    
        return 0;
    }