Linux下USB摄像头采集图像,液晶framebuffer显示

前面说了使用USB摄像头采集bmp图片和yuv视频,显示过程直接就是把bmp图片在lcd显示出来就可以了。大体的USB摄像头操作和前面的一样,不清楚摄像头操作可以去
http://blog.csdn.net/zhangdaxia2/article/details/72763847。Framebuffer操作也不难,具体如下:
framebuffer设备节点为/dev/fbx。一般为/dev/fb0,一个液晶控制节点。操作步骤:

1、打开framebuffer。

int fd = -1;
fd = open("/dev/fb0", O_RDWR);

2、ioctl获取LCD参数。

static struct fb_fix_screeninfo fixinfo;
static struct fb_var_screeninfo varinfo;
ret = ioctl(fb_fd, FBIOGET_VSCREENINFO, &varinfo);
ret = ioctl(fb_fd, FBIOGET_FSCREENINFO, &fixinfo);

3、进行mmap内存地址映射,将内核地址映射到用户空间,用户直接向映射的地址写入数据,就可将数据显示到LCD上。

fbmmap = (int*)mmap(NULL, fixinfo.smem_len, PROT_READ | PROT_WRITE, MAP_SHARED,
        fb_fd, 0);
if(NULL == fbmmap){
        printf("mmap memeory error.\n");
        exit(0);
    }

4、向映射后的地址中写入数据,绘制framebuffer。

void fb_drawbmp(uint height,uint width,unsigned char* pdata)
{
    uint x,y,cnt;
    uint a = height*width*3;
    uint cnt1 = 0;
    uint* p = fbmmap;
    for(x=0; xfor(y=0; y// LCD像素位置
            cnt1 = (x*width+width-y)*3;         // 图片像素位置,width-y用于解决图像显示左右反了的问题
            *(p+cnt) = (pdata[cnt1]<<0) | (pdata[cnt1+1]<<8) | (pdata[cnt1+2]<<16);
        }
}

5、在USB摄像头操作readfram()中,将fb_drawbmp()放到里头,把摄像头采集的数据转成RGB后,直接写入framebuffer,就可以完成LCD显示摄像头图像。

static int readfram()
{
    struct pollfd pollfd;
    int ret,i;
    char filename[50];
for(i =0; i<10 ;i++){
        memset(&pollfd, 0, sizeof(pollfd));
        pollfd.fd = fd;
        pollfd.events = POLLIN;
        ret = poll(&pollfd, 1, 800);
        if(-1 == ret){
            perror("VIDIOC_QBUF fail.\n");
            return -1;
        }else if(0 == ret){
            printf("poll time out\n");
            continue;
        }
    if(pollfd.revents & POLLIN){
        memset(&buf, 0, sizeof(buf));
        buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
        buf.memory = V4L2_MEMORY_MMAP;
        ret = ioctl(fd, VIDIOC_DQBUF, &buf);
        if(0 != ret){
            perror("VIDIOC_QBUF fail.\n");
            return -1;
        }
        //v4l2_buffer
        // 直接保存的yuyv数据
        //FILE *file = fopen(YUYV_FILE, "wb");
        //ret = fwrite((char*)framebuf[buf.index].start, 1, buf.length, file);
        //fclose(file);

        // RGB格式数据
        starter = (unsigned char*)framebuf[buf.index].start;
        newBuf = (unsigned char*)calloc((unsigned int)(framebuf[buf.index].length*3/2),sizeof(unsigned char));
        yuv422_2_rgb();
        // 将RGB数据写入到framebuffer,在LCD上显示
        fb_drawbmp(height, width, newBuf);

        ret = ioctl(fd, VIDIOC_QBUF, &buf);
        }
    }
    return ret;
}

由于Ubuntu和Android会不断的刷新屏幕,所以在这些系统上实验不一定有想过。在Linux开发板上可以正
常运行,显示出摄像头图像。
包括USB摄像头操作的完整代码可从以下网址下载:
https://github.com/zhangdalei/video_lcd_show

你可能感兴趣的:(Linux应用,摄像头,linux,framebuffer,usb,图片)