繁体   English   中英

将unsigned char * image转换为OpenCV Mat的问题

[英]Issue converting unsigned char * image to OpenCV Mat

我有一个问题是将图像数据从帧抓取器解析为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();

我编写了一个代码,用于绘制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垫,数据的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然后转换它。

暂无
暂无

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

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