• 11766阅读
  • 11回复

Linux摄像头编程小结 [复制链接]

上一主题 下一主题
离线keisuo
 

只看楼主 倒序阅读 楼主  发表于: 2007-05-29
— 本帖被 XChinux 执行加亮操作(2008-07-18) —
linux下开发摄像头的程序,主要用的是video4linux来做的,界面用qt来实现,开始准备用frame buffer来直接写屏但是效果不怎么好,后来就用qt来做了,这样用起来效果还蛮好的,帧率也可以,可以上到30fps;运用v4l来编程主要掌握其 api,要提高帧率最重要的是用到内存映射,其实用qt和frame buffer的时候都要用到内存映射来做,只有这样才可以达到较高的帧率,不过要注意资源的利用问题.mmap后一定要munmap.对于frame buffer是很有意思的一个东西,特别是驱动的设计.
[ 此贴被XChinux在2008-07-18 16:47重新编辑 ]
离线keisuo

只看该作者 1楼 发表于: 2007-05-29
这次是在linux下开发摄像头的程序,主要用的是video4linux来做的,界面用qt来实现,开始准备用frame buffer来直接写屏但是效果不怎么好,后来就用qt来做了,这样用起来效果还蛮好的,帧率也可以,可以上到30fps;运用v4l来编程主要掌握其 api,要提高帧率最重要的是用到内存映射,其实用qt和frame buffer的时候都要用到内存映射来做,只有这样才可以达到较高的帧率,不过要注意资源的利用问题.mmap后一定要munmap.对于frame buffer是很有意思的一个东西,特别是驱动的设计.
代码如下:
1.open device:
      video_dev = open("\dev\video0",O_RDWR));
2.get the information of the video device
    struct video_capability video_cap;
    memset(&video_cap,0,sizeof(video_cap));
    if(ioctl(video_dev,VIDIOCGCAP,&video_cap) == -1)
    {
        perror("Cann't get the information of the video device");
        close(video_dev);
        exit(1);
    }
3.get the information of the channels
    struct video_channel video_chan;
    memset(&video_chan,0,sizeof(video_chan));
    for(channel = 0;channel < video_cap.channels;channel++)
    {
        video_chan.channel = channel;
        if(ioctl(video_dev,VIDIOCGCHAN,&video_chan) == -1)
        {
            perror("Cann't get the information of the channels");
            close(video_dev);
            exit(3);
        }
        if(video_chan.type == VIDEO_TYPE_TV)
        {
                  #ifdef DEBUG
            printf("NO.%d channel is %s,type is tv!\n",channel,video_chan.name);
                  #endif
        }
        if(video_chan.type == VIDEO_TYPE_CAMERA)
        {
            if(ioctl(video_dev,VIDIOCSCHAN,&video_chan) == -1)
            {
                perror("Cann't set the camera channel!");
                close(video_dev);
                exit(4);
            }
        }
    }
4.get the capture attributes
    struct video_picture video_pic;
    memset(&video_pic,0,sizeof(video_pic));
    if(ioctl(video_dev,VIDIOCGPICT,&video_pic) == -1)
    {
        perror("Cann't get the picture attributes of the device!");
        close(video_dev);
        exit(5);
    }
5.set capture attributes
      video_pic.palette = VIDEO_PALETTE_*****;//different camera has different palette
      video_pic.brightness = 65535;
    video_pic.colour = 0;
    if(ioctl(video_dev,VIDIOCSPICT,&video_pic) == -1)
    {
        perror("Cann't set the picture attributs!");
        close(video_dev);
        exit(6);
    }
6.mmap the device
    struct video_mbuf mbuf;
    unsigned char *frames;
    memset(&mbuf,0,sizeof(mbuf));
    if(ioctl(video_dev,VIDIOCGMBUF,&mbuf) == -1)   
    {
        perror("Cann't get the buffer information of the video device!");
        close(video_dev);
        exit(7);
    }
    frames = (unsigned char *)::mmap(0,mbuf.size,PROT_READ|PROT_WRITE,MAP_SHARED,video_dev,0);
    if(!frames || frames == (unsigned char *)(long)(-1))
    {
        perror("The device cann't be memory mapped!");
        close(video_dev);
        exit(8);
    }
7.capture
            if(ioctl(video_dev,VIDIOCMCAPTURE,&mmap) == -1)
        {
            perror("Capture failed!");
            close(video_dev);
            exit(9);
        }
   
        else
        {
                  //display or save the picture file
            }
离线aaniao999

只看该作者 2楼 发表于: 2007-05-31
谢谢,我去找找video4linux来试试看,以前找的不是这个
离线duduqq

只看该作者 3楼 发表于: 2009-06-16
谁有完整的代码
离线xymail110
只看该作者 4楼 发表于: 2009-06-17
        我们的项目也有linux下的摄象头编程,但是我们没有直接写framebuffer,就是用qt实现的,就是将采集的一帧视频数据用qbitmap显示出来,效果似乎也不错啊。
        不过还有些小的细节问题,希望能与楼主交流一下.
学无止境
离线zyq840112

只看该作者 5楼 发表于: 2009-12-17
我在获取通道:if (ioctl(vd->fd, VIDIOCGCHAN, &(vd->channel)) < 0) 和内存映射:if (ioctl(vd->fd, VIDIOCGMBUF, &(vd->mbuf)) < 0)这两个地方的返回都小于0。但检查代码确没有问题。请问这是什么原因?谢谢!
离线zyq840112

只看该作者 6楼 发表于: 2009-12-17
请高手帮忙!
离线duduqq

只看该作者 7楼 发表于: 2009-12-17
用OpenCV来打开摄像头并把获取的图片转成QImage显示到界面上就行了。
离线zyq840112

只看该作者 8楼 发表于: 2009-12-18
谢谢楼上的提示!
离线slbbls
只看该作者 9楼 发表于: 2010-01-06
引用第5楼zyq840112于2009-12-17 17:00发表的  :
我在获取通道:if (ioctl(vd->fd, VIDIOCGCHAN, &(vd->channel)) < 0) 和内存映射:if (ioctl(vd->fd, VIDIOCGMBUF, &(vd->mbuf)) < 0)这两个地方的返回都小于0。但检查代码确没有问题。请问这是什么原因?谢谢!


哎,一样的问题啊,这是怎么回事啊,
我用的是2440的开发板,他上面自带的qtopia可以显示摄像头的,可是我的程序也一样的错误,
应该不是驱动的问题吧??
离线lishiyong110
只看该作者 10楼 发表于: 2010-02-26
引用第9楼slbbls于2010-01-06 13:36发表的  :
哎,一样的问题啊,这是怎么回事啊,
我用的是2440的开发板,他上面自带的qtopia可以显示摄像头的,可是我的程序也一样的错误,
应该不是驱动的问题吧??


我的也是,希望能有高手指点下...还有我使用的是linux-2.6.12
[ 此帖被lishiyong110在2010-02-26 19:11重新编辑 ]
静下心来学习
离线weizhu
只看该作者 11楼 发表于: 2010-02-27
各位,我现在也在做这些工作,我的感觉是:我直接写fb要效果好的多,用qt显示反倒特差,不知道大家有什么提示?我的摄像头驱动没有用video4linux
快速回复
限100 字节
 
上一个 下一个