v4l2抓取图片打不开

6 篇文章 0 订阅

    搞linux下音视频是不能离开v4l2的。前段时候想自己写个利用v4l2 API直接抓取图像的测试程序。网上一查有很多相关的程序。我下载下来编译后运行,发现图片是抓取到了,可是不能打开,摄像头抓取的一般都是YUYV格式的,直接存成文件缺乏相应头文件信息肯定打不开。下面是我写的一个简单的转换成rgb24,再存成ppm格式,图片正常打开。

#include <stdio.h>
#include <math.h>
#include <errno.h>
#include <malloc.h>
#if 0
#define TO_R(y, u, v)    floor((float)y + 1.140 *((float)v))
#define TO_G(y, u, v)    floor((float)y - 0.394 * (float)u - 0.581 * (float)v)
#define TO_B(y, u, v)    floor((float)y + 2.032 * (float)u)
#else
#define TO_R(y, u, v)    floor(1.164 * (y - 16) + 1.159 * (v - 128))
#define TO_G(y, u, v)    floor(1.164 * (y - 16) - 0.38 * (u - 128) - 0.813 * (v - 128))
#define TO_B(y, u, v)    floor(1.164 * (y - 16) + 2.018 * (u - 128))
#endif
#define CLIP(x) if (x > 255) x = 255; \
                else if (x < 0) x = 0;
                
// need free rgb by user;
int YuyvToRgb24(const char * const yuv, const int in_size,
                char **const rgb, int * const out_size, int w, int h)
{
    const unsigned char *pyuv = yuv;
    char *prgb = NULL;

    int pix = w * h;
    prgb = malloc(pix * 3);
    if (prgb == NULL)
    {
        perror("malloc:");
        return -1;
    }
    float R, G, B, Y, U, V;
    int i, j;
    for (i = 0, j = 0; i < pix * 2; i += 4)
    {
        // pixe0
        Y = pyuv[i];
        U = pyuv[i + 1];
        V = pyuv[i + 3];
        R = TO_R(Y, U, V);
        G = TO_G(Y, U, V);
        B = TO_B(Y, U, V);
        CLIP(R);
        CLIP(G);
        CLIP(B);
        prgb[j++] = (unsigned char)R;
        prgb[j++] = (unsigned char)G;
        prgb[j++] = (unsigned char)B;
        // pixe1
        Y = pyuv[i + 2];
        R = TO_R(Y, U, V);
        G = TO_G(Y, U, V);
        B = TO_B(Y, U, V);
        CLIP(R);
        CLIP(G);
        CLIP(B);
        prgb[j++] = (unsigned char)R;
        prgb[j++] = (unsigned char)G;
        prgb[j++] = (unsigned char)B;

    }

    *out_size = pix * 3;
    *rgb = prgb;

    return 0;
}

如果图片颜色不对,可以试着换下TO_R,TO_G,TO_B的公式。

存成ppm文件函数

int WriteToPpm(const char * const data, int size, int w, int h)
{
    static int frame = 0;
    char name[64] = {0};
    snprintf(name, sizeof(name), "frame%d.ppm\0", frame++);
    FILE *fp = fopen(name, "wb");
    if (fp < 0)
    {
        printf("open frame data file failed\n");
        return -1;
    }
    fprintf(fp, "P6\n%d %d\n255\n", w, h);

    char *rgb;
    int rgb_size;
    YuyvToRgb24(data, size, &rgb, &rgb_size, w, h);
    fwrite(rgb, rgb_size, 1, fp);
    free(rgb);
    
    printf("Capture one frame saved in %s\n", CAPTURE_FILE);
    
    fclose(fp);
    
    return 0;
}



  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值