Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

OpenCV: Working with 12bit gray scale raw data

In past I have used OpenCv for processing 32 bit .bmp files, and have got successful results. How do I make use of Opencv functions to process 12bit raw data? My processing will be mostly operations like finding the some of 1000 pixels and so on.

EDIT The file that I am getting is .bin file. And the Pixels in Image are placed like this(the file has all the content like this, coz I am taking a picture of white paper):

(FF)(0F)(FF)(0F)(FF)(0F)(FF)(0F)(FF)(0F)(FF)(0F)(FF)(0F)

Clearly I can do 16 bit processing on this.

like image 480
gpuguy Avatar asked Jun 18 '12 07:06

gpuguy


3 Answers

Well I wanted to do 16 bit processing on this image. The secret is then reveled in another question .

For 16 bit I will have to switch to PNG not bmp!

This document says I can use 16 bit PNG in OpenCV

like image 143
gpuguy Avatar answered Nov 12 '22 23:11

gpuguy


From what I know, OpenCV is only handling 8, 16 and 32 bits images correctly.

depending on what you want to do, you should

  • either transforming your 12 bits image into 8bits (assuming it s a 12 bits bayer encoded image)
  • or convert it manually to 16 by padding the values with zeros. From what I found here, this might already been done on your image.

I'd advise you to look closer at how your pixels are exactly placed in your image before doing anything. This will greatly help you to know what is best. A good way to do this is using bless or another hex editor

EDIT:

Taken from here, Your data are (I think) encoded over 16 bits with padding

Simply convert from 16 bits to 8 bits using Opencv should do the trick, as it is what is done while converting to JPEG. Have you at least tried ?

like image 24
jlengrand Avatar answered Nov 12 '22 22:11

jlengrand


Left shift the bits and store them as 16bit.

For a monochrome camera:

cv::Mat imgOpenCV = cv::Mat(cv::Size(img->width, img->height), CV_16UC1, (char*)img->imageData, cv::Mat::AUTO_STEP); //Convert the raw image
imgOpenCV.convertTo(imgOpenCV, CV_16UC1, 1.0*(2^4), 0.0); //Shift left 4 bits

For a color camera:

// Convert the image using the manufacturer's SDK (Imperx in this case)
IpxImage* imgConverted = nullptr;
IpxError err = IPX_CAM_ERR_OK;
IpxSize imgSize;
imgSize.height = img->height;
imgSize.width = img->width;
uint32_t pixelType = II_PIX_BGR12;
err = IpxCreateImage(&imgConverted, imgSize, pixelType);
err = IpxBayer_ConvertImage(hBayer, img, imgConverted);

// Create OpenCV converted image
cv::Mat imgOpenCV = cv::Mat(cv::Size(imgConverted->width, imgConverted->height), CV_16UC3, (char*)imgConverted->imageData, cv::Mat::AUTO_STEP); //Convert the image
imgOpenCV.convertTo(imgOpenCV, CV_16UC3, 1.0*(2^4), 0.0); //Shift left 4 bits

You could also use the manufacturer's SDK to convert to 16 bit directly, but I suspect this scales the bit depth instead of shifting it in some cases. I'd rather preserve the raw bit depth information, so doing the shift myself prevents me from having to look under the hood when I switch manufacturers (GigE cameras force you to use the manufacturer SDK unfortunately).

like image 1
VoteCoffee Avatar answered Nov 12 '22 23:11

VoteCoffee