将无符号字符 * 图像转换为 OpenCV Mat 时出现问题

Issue converting unsigned char * image to OpenCV Mat

本文关键字:Mat 问题 OpenCV 字符 无符号 图像 转换      更新时间:2023-10-16

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

我的相机是一个红外相机,输出12位320x256拜耳图像。我相当有信心我对EDT的API的使用是正确的。使用EDT的软件"pdvshow",我可以按预期查看图像数据,但是当我将返回的帧从EDT的API转换为OpenCV Mat并显示它时,我丢失了大量数据。当我将垫子设置为CV16UC1时,帧接近黑色,当垫子设置为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();

我写了一个代码来绘制一个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;
    }
}

我希望这会有所帮助!

当您将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垫,最简单的可能是创建一个CV_16UC1垫,然后转换它。