【问题标题】:Issue converting unsigned char * image to OpenCV Mat将 unsigned char * 图像转换为 OpenCV Mat 的问题
【发布时间】:2013-10-10 21:11:16
【问题描述】:

我在将图像数据从图像采集卡解析为 OpenCV Mat 格式时遇到问题。我可以从我的 EDT 图像采集卡获取图像数据作为无符号字符指针并将其传递给新创建的 Mat,但我在此过程中丢失了有价值的数据并且不知道如何修复它。

我的相机是红外相机,它输出 12 位 320x256 拜耳图像。我相当有信心我对 EDT API 的使用是正确的。使用 EDT 的软件“pdvshow”,我可以按预期查看图像数据,但是当我将返回的帧从 EDT 的 API 转换为 OpenCV Mat 并显示它时,我会丢失大量数据。当我将 Mat 设置为 CV16UC1 时,框架接近黑色,当 Mat 设置为 CV8UC1 时,框架显示大部分数据,但显得非常颗粒状,并且一些斑点完全被吹掉。我知道图像采集卡将每个 12 位像素存储在两个字节中,并且数据是 MSB 对齐的。 GetStride 返回 0。

unsigned char *pdvImage;
pdvImage = pdv_image(pdv_p); 

cv::Mat freshFrame;
freshFrame = cv::Mat(GetHeight(), GetWidth(), CV_16UC1, pdvImage, GetStride()); //was CV_16UC1 but 8UC1 shows more data

return freshFrame.clone();

【问题讨论】:

    标签: c++ opencv image-processing computer-vision mat


    【解决方案1】:

    我已经编写了一个代码,它可以绘制一个 char* 图像,然后将其转换为 OpenCV Mat:

    const int WIDTH = 800, HEIGHT = 600;
    
    uchar *data = new uchar[WIDTH * HEIGHT * 3];
    
    for (int i = 0; i < WIDTH*HEIGHT*3;i+=3)
    {
        if (i < WIDTH*HEIGHT*3/2)
        {
            data[i + 0] = (uchar)0;
            data[i + 1] = (uchar)0;
            data[i + 2] = (uchar)255;
        }
        else
        {
            data[i + 0] = (uchar)255;
            data[i + 1] = (uchar)0;
            data[i + 2] = (uchar)0;
        }
    }
    
    cout << "May God be pleased with you, amen!\n";
    
    Mat colorfrm = Mat(HEIGHT, WIDTH, CV_8UC3);
    colorfrm.data = data;
    
    while (1)
    {
        imshow("Original Image", colorfrm);
    
        /////////
    
        int c = cvWaitKey(30);
        if (c == ' ')
        {
            break;
        }
        if (c == 'q' || c == 'Q' || c == 27)
        {
            return 0;
        }
    }
    

    我希望这会有所帮助!

    【讨论】:

      【解决方案2】:

      当您将freshFrame 创建为 CV_16UC1 Mat 时,12 位数据位于最低有效位中。缩放数据将解决结果图像显得太黑的问题。所以不是

      return freshFrame.clone();
      

      你需要

      return freshFrame * 16;
      

      您可能还需要检查pdvImage 中每个像素的两个字节的字节顺序。

      对于 CV_8UC1,这将不起作用

      freshFrame = cv::Mat(GetHeight(), GetWidth(), CV_8UC1, pdvImage, GetStride()); 
      

      因为pdvImage的前两个字节组成了图像中第一个像素的值,但在freshFrame中变成了两个独立的像素。但是,如果您在上面的行中创建freshFrame,则第一个字节将成为freshFrame 中第一个像素的值,第二个字节将成为第二个像素的值,依此类推。显然这是错误的。如果您真的需要 CV_8UC1 Mat,最简单的方法可能是创建一个 CV_16UC1 Mat 然后转换它。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2016-09-04
        • 2020-09-15
        • 1970-01-01
        • 2018-09-04
        • 1970-01-01
        • 2011-10-19
        • 2013-09-23
        相关资源
        最近更新 更多