Issue converting unsigned char * image to OpenCV Mat

user2640018 picture user2640018 · Oct 4, 2013 · Viewed 10.4k times · Source

I have an issue parsing the image data from the frame grabber into an OpenCV Mat format. I can get image data from my EDT frame grabber as an unsigned char pointer and pass it to a newly created Mat, but I am losing valuable data in the process and am not sure how to fix it.

My camera is an infrared camera which outputs a 12-bit 320x256 Bayer image. I'm fairly confident that my use of EDT's API's is correct. Using EDT's software, "pdvshow", I can view the image data as expected but when I convert the returned frame from EDT's API to an OpenCV Mat and display it, I lose a significant amount of data. When I have the Mat set to CV16UC1, the frame is near black, when the Mat is set to CV8UC1, the frame displays most data but appears very grainy and some spots are blown out completely. I know that the frame grabber stores each 12-bit pixel in two bytes and the data is MSB justified. GetStride returns 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();

Answer

Hasan Zakaria Alhajhamad picture Hasan Zakaria Alhajhamad · Oct 17, 2014

I have written a code that draws a char* image then convert it to 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;
    }
}

I hope this will be of help!