简体   繁体   English

如何处理来自 MIPI 相机的 12 位图像?

[英]how handle 12-bit image from MIPI camera?

Actually, I use a Gige camera.实际上,我使用的是 Gige 相机。 That camera provide images in unsigned char* , this mean a bit depth of 8. I develop in c/c++.该相机以unsigned char*提供图像,这意味着位深度为 8。我使用 c/c++ 开发。

I am going to receive a new one, but that camera is different.我将收到一台新的,但那台相机不同。 This one provides void* , with a bit depth of 12. Can I cast the void* like that:这个提供void* ,位深为 12。我可以像这样投射void*吗:

unsigned short* img ;
img = (unsigned short*) camera.GetImage() ; /**camera.GetImage() is void*/

It is new for me, and I have been never using raw format.这对我来说是新的,我从来没有使用过原始格式。 Does cast is a good idea?演员是个好主意吗? I need to access at each pixel, and I don't how handle pixel with void* .我需要访问每个像素,我不知道如何使用void*处理像素。

I suggest to cast with unsigned short* because of the depth.由于深度,我建议使用unsigned short*进行投射。 The pixel of the camera are encoded on 12. If I cast with unsigned char* , I would lose information.相机的像素在 12 上编码。如果我使用unsigned char*投射,我会丢失信息。

Thank you for your help !谢谢您的帮助 !

UPDATE更新

Thank you a lot for all your details.非常感谢您提供的所有详细信息。 As I am a beginner, your answer help me a lot to find other ways to investigate.由于我是初学者,您的回答对我找到其他调查方法有很大帮助。

I am working on jetson TX2, and the bit location is a reflection of the actual hardware.我正在研究jetson TX2,位位置是实际硬件的反映。

For my part, the pixel data is concatenated in 16bits.就我而言,像素数据以 16 位连接。 The output of the jetson TX2 is: jetson TX2的output为:

              ONE PIXEL

|              16 bits                          |
D5-D4-D3-D2-D1-D0-D11-D10-0-0-D11-D10-D9-D8-D7-D6

My goal is not to display the image.我的目标不是显示图像。 Below the explanation of my process:下面是我的过程的解释:

1 - Take 5 times the same image; 1 - 拍摄 5 次相同的图像;

2 - Calculation of the average image; 2 - 平均图像的计算;

3 - Bad pixels correction; 3 - 坏像素校正;

4 - Flat field correction; 4 - 平场校正;

4 - Send final image through socket; 4 - 通过套接字发送最终图像;

In a thread, I acquire images.在一个线程中,我获取图像。 In an other thread, I apply image processing and in an other one, I send image through socket.在另一个线程中,我应用图像处理,在另一个线程中,我通过套接字发送图像。 I implemented all the process.我实施了所有过程。

I didn't use libraries like openCV because I did some specifics process.我没有使用像 openCV 这样的库,因为我做了一些具体的过程。 I need to handle all pixels of the image, and I wonder if it is very efficient to convert the .raw in unsigned short* , to adapt the image to my code.我需要处理图像的所有像素,我想知道将.raw转换为unsigned short*是否非常有效,以使图像适应我的代码。

The 'packing' was never a question because my previous camera provides images in an unsigned char* . “包装”从来都不是问题,因为我以前的相机以unsigned char*提供图像。 Do you think that I should convert the void* into unsigned short* ?您认为我应该将void*转换为unsigned short*吗?

Thank you for your help谢谢您的帮助

There is not enough information in your post to answer your question.您的帖子中没有足够的信息来回答您的问题。 Here are the possible packing for 12-bits pixels:以下是 12 位像素的可能打包方式:

Efficient packing高效包装


Bit0     Bit11     Bit23      Bit35        Bit47     Bit59     Bit71     Bit83      Bit95
[ Pixel0   | Pixel1  | Pixel2    | Pixel3  | Pixel4   | Pixel5  | Pixel6  |  Pixel7 ]  (that is 8 pixels per 96bits or 3 32-bits word) 

Easy to use packing易于使用的包装


Bit0    Bit11     Bit23    Bit32     Bit43     Bit55     Bit63     
[ Pixel0   | Pixel1  | 0    | Pixel3  | Pixel4   | 0      ]  (that is 2 pixels per 32-bits word) 

Dumb packing哑包装


Bit0    Bit11     Bit16    Bit27     Bit31          
[ Pixel0   |  0    | Pixel1  |  0      ]  (that is 1 pixels per 16-bits word) 

You have to read the datasheet of your camera to figure which packing is being used.您必须阅读相机的数据表才能确定正在使用哪种包装。 Once this is done, you also need to figure out the endianness of the data for transmitting the data words.完成此操作后,您还需要确定数据的字节顺序以传输数据字。 For example, in a little endian system, you'll the least significant byte first.例如,在小端系统中,您将首先使用最低有效字节。 For a big endian system, you'll get the most significant byte first.对于大端系统,您将首先获得最高有效字节。 You'll need to adapt your pixel extraction code to fit your machine's endianness.您需要调整像素提取代码以适应您机器的字节序。

Extracting pixel is done quite simply once you have figured out the packing and endianness with bit shifting and mask.一旦您通过位移和掩码弄清楚了打包和字节序,提取像素就非常简单了。

Since you have asked for a C++ solution, here's a any-bit extractor from a memory stream, you'll need to adjust for the packing and endianness:由于您要求 C++ 解决方案,这里有一个来自 memory stream 的任意位提取器,您需要调整包装和字节序

struct BitStream
{
    const uint8 * begin;
    const uint8 * end;
    size_t pos;
    BitStream(const uint8 * bits, size_t len) : begin(bits), end(bits + len), pos(0) {}
    // get value from bitstream coded on len bits
    uint32 get(uint8 len)
    {
        size_t byte_offset = pos/8;
        uint8 bit_pos = pos % 8;
        uint8 bit_avail = 8 - bit_pos;
        if (begin+byte_offset >= end) return 0;
        if (bit_avail >= len)
        {
            uint32 value = begin[byte_offset];
            uint8 mask = ~(0xff << len) << bit_pos;
            value = value & mask;
            value = value >> bit_pos;
            pos = pos + len;
            return value;
        }
        else
        {
            uint32 value = get(bit_avail);
            value = value | (get(len - bit_avail)<<bit_avail);
            return value;
        }
    }
    void skip(uint8 len) { pos += len; }
    bool done() const { return (begin + pos/8) >= end; }
};

If there is endianness mismatch between the camera and your machine, you'll need to swap the returned pixel like this:如果相机和您的机器之间存在字节顺序不匹配,您需要像这样交换返回的像素:

BitStream bs((const uint8*)camera.getImage(), camera.getImageLen());
// Get pixel
uint16 pixel = (uint16)bs.get(12);
// Comment the line below if the endianness is the same
pixel = ((pixel & 0xFF00) >> 8) | (pixel << 8);
// Skip the stuffing zero bits depending on packing format, here I assume dumb packing
bs.skip(4); 

Thank you for updating your question.感谢您更新您的问题。

If, as it now seems, each 12-bit pixel is fully contained in a 16-bit unsigned short with 4-bits of padding, then "yes" unsigned short is definitely the way to go.如果现在看起来,每个 12 位像素都完全包含在 16 位无符号短字节中,并带有 4 位填充,那么“是”无符号短字节绝对是通往 go 的方法。 I don't know if your environment has uint16_t or not but that is guaranteed to be exactly 16-bits (which I feel is better) whereas unsigned short is "at least" 16-bits.我不知道您的环境是否具有uint16_t ,但可以保证恰好是16 位(我觉得更好),而unsigned short“至少” 16 位。

Now you just need to do some ANDing and shifting...现在你只需要做一些 ANDing 和 shift...

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

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