描述我的原始摄影机输出

2024-04-20 14:10:36 发布

您现在位置:Python中文网/ 问答频道 /正文

我的Leopard Imaging M021 camera有个很奇怪的问题。该公司并不真正支持linux,因此摄像头只能输出原始数据。我需要它在Beagleboard上运行,这就是为什么我要努力让它工作。在

他们的一位员工告诉我它是在YUY2 format(通常是每像素16位),但是高4位总是0,低12位包含如下信息: YUYV description

使用命令:

fswebcam --device /dev/video0 --resolution 1280x720 --dumpframe test.raw

我得到一个1843200字节长的文件,这意味着一个1280x720图像,每像素2个字节(每像素16位)。在

然而,我能够真正使图像正确显示的唯一方法是使用IrfanView的原始图像显示,并将其设置为每像素12位,而不是标准化,使用GR的bayer模式,并进行垂直翻转。我不知道为什么需要垂直翻转,因为其他设置将显示一个倾斜的,奇怪的图像,但不是翻转。然后我用12个基点,它被翻转了。在

IrfanView Params

我想既然高4位总是0,那么它实际上是每像素12位而不是16位?在

为了自己编写转换算法,我需要知道文件中字节的实际情况(除非有人知道有一个开源程序与IrfanView做同样的事情)。在

使用Python,我编写了一个非常快速的脚本,只需拉出Y组件并查看它(需要图像的灰度版本),但是我得到了一个非常扭曲的版本。我的代码有问题吗?我是不是把数据取错了顺序?在IrfanView中“不规范化”是什么意思?为什么要在RGB中查看图像需要GR-Bayer模式设置?在

^{pr2}$

生成的垃圾图像: enter image description here

我将感谢任何人在这方面的帮助或建议。在

编辑:

进一步的可能有用的证据。如果我在matlab中运行,只需将每2个字节作为精确的像素值:

fid = fopen('test.raw', 'r');
[I, count] = fread(fid , [1280, 720], 'uint16');
imagesc(I')
colormap(gray);

我得到的图像是: sort of decent looking picture but no color

我仍然缺少颜色信息,因为我忽略了它。而且还是有点歪斜。但看起来好多了。如果你放大,图像倾斜的模式是好像素,黑像素,好像素,黑像素等等。有人更了解相机和颜色,知道这是什么指示吗?在

编辑2:

在markransom的专家帮助下,我编写了一个很好的OpenCV脚本来读取数据,利用CV_BayerGR2RGB转换成RGB,并查看图像。它起作用了!在

#include <vector>
#include <iostream>
#include <stdio.h>
#include <opencv2/opencv.hpp>
#include <opencv2/highgui/highgui.hpp>

int main() {
    // Each pixel is made up of 16 bits, with the high 4 bits always equal to 0
    unsigned char bytes[2];

    // Hold the data in a vector
    std::vector<unsigned short int> data;

    // Read the camera data
    FILE *fp = fopen("test.raw","rb");
    while(fread(bytes, 2, 1, fp) != 0) {
        // The data comes in little-endian, so shift the second byte right and concatenate the first byte
        data.push_back(bytes[0] | (bytes[1] << 8));
    }

    // Make a matrix 1280x720 with 16 bits of unsigned integers
    cv::Mat imBayer = cv::Mat(720, 1280, CV_16U);

    // Make a matrix to hold RGB data
    cv::Mat imRGB;

    // Copy the data in the vector into a nice matrix
    memmove(imBayer.data, data.data(), data.size()*2);

    // Convert the GR Bayer pattern into RGB, putting it into the RGB matrix!
    cv::cvtColor(imBayer, imRGB, CV_BayerGR2RGB);

    cv::namedWindow("Display window", cv::WINDOW_AUTOSIZE);
    // *15 because the image is dark
    cv::imshow("Display window", 15*imRGB);

    cv::waitKey(0);

    return 0;
}

Tags: thetest图像dataraw字节bytesinclude
1条回答
网友
1楼 · 发布于 2024-04-20 14:10:36

你所掌握的证据,首先是每个字节的高位4位是0,而且你可以从Irfanview看到一张合适的彩色图片,这说明这个雇员是错误的,格式实际上并不YUY2—它是GRGB。在

这段代码应该将绿色像素拉出来,并将它们加倍,这样您就可以了解图像的外观。请注意,偶数和奇数行将在以G开头和(R或B)之间交替。在

with open('test.raw', 'r+b') as f:
    raw_g = []
    for y in range(720):
        for x in range(1280//4):
            if y % 2:
                r1, r0, g1, g0, b1, b0, g3, g2 = f.read(8)
            else:
                g1, g0, r1, r0, g3, g2, b1, b0 = f.read(8)
            g0 = g0 << 8 | g1
            g2 = g2 << 8 | g3
            raw_g.extend([g0, g0, g2, g2])

在将这些值写入灰度文件之前,您可能需要右移这些值>> 4。在

编辑:代码还有一个bug(额外读取),我没有意识到这些值是little-endian而不是big-endian。这些更改已经应用于上面的代码示例。在

因为值看起来有点暗,所以我决定应用gamma校正,而不是使用n >> 4而使用int(255.999 * (n / 4095.0)**(1/2.2))

green channel with gamma correction

恐怕德拜仁有点超出了我在一个简短的StackOverflow回答中所能做到的。在

相关问题 更多 >