• 6918阅读
  • 6回复

【提问】如何连续显示从摄像头获取得图片 [复制链接]

上一主题 下一主题
离线doublezha
 

只看楼主 倒序阅读 楼主  发表于: 2006-02-21
我编了个程序,截取摄像头的图片,用定时器设置4s截取一幅存为1.png,然后紧接着去读这幅图片,并在QLabel中显示出来,如此反复,可是现在发现可能是定时器设置的问题,程序读图片时老是没读到已经截取完毕的图片(有时候图片还没截取完,就去读1.png了),所以也无发显示出来.各位大大有谁遇到过,帮我解决一下!
只看该作者 1楼 发表于: 2006-02-21
我有相同的问题,可以多存储几张,延时读取
离线doublezha

只看该作者 2楼 发表于: 2006-02-22
谢谢你的点拨!
离线XChinux

只看该作者 3楼 发表于: 2006-02-23
这是个不错的变通的方法
二笔 openSUSE Vim N9 BB10 XChinux@163.com 网易博客 腾讯微博
承接C++/Qt、Qt UI界面、PHP及预算报销系统开发业务
离线wan198411

只看该作者 4楼 发表于: 2006-03-11
我问个新手的问题啊
怎么把usb摄像头的图片截取保存下来呢?
离线txf1949

只看该作者 5楼 发表于: 2008-04-14
Re:【提问】怎么在qt下显示摄像头获取的信息
我在做基于qt下显示摄像头获取的信息,就是显示不出来,大家看看我错在哪个地方啊 ?
#include <qapplication.h>
#include <qpushbutton.h>
#include <qwidget.h>
#include <qcolor.h>
#include <qtimer.h>
#include <qframe.h>
#include <math.h>
#include <qimage.h>
#include <qpainter.h>

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <linux/videodev.h>
#include <sys/ioctl.h>
#include <fcntl.h>
#include <linux/fb.h>
#include <sys/mman.h>
#include <string.h>

#define ERR_FRAME_BUFFER 1
#define ERR_VIDEO_OPEN  2
#define ERR_VIDEO_GCAP  3
#define ERR_VIDEO_GPIC  4
#define ERR_VIDEO_SPIC  5
#define ERR_SYNC    6
#define ERR_FRAME_USING  7
#define ERR_GET_FRAME    8
int screensize;
#define V4L_FILE "/dev/video0"
#define DEFAULT_PALETTE VIDEO_PALETTE_RGB565



class MyWidget : public QWidget
{
//O_OBJECT
public:
    MyWidget( QWidget *parent=0, const char *name=0 );
    //unsigned char* get_image();
    //void get_image();
    int open_video();   
    int get_grab_frame();
    //void paintEvent(QPaintEvent *);
//protected:
    //virtual void paintEvent(QPaintEvent *);
    void paintEvent(QPaintEvent *);
private:
    QTimer *timer;
    QFrame *frame;
    //unsigned short* imageptr;
    unsigned short* imageptr;
    int dep;
    int pal;
    int width;
    int height;
    // FrameBuffer 信息
    struct fb_var_screeninfo vinfo;  // FrameBuffer屏幕可变的信息
    struct fb_fix_screeninfo finfo;  // FrameBuffer固定不变的信息
    //video4linux信息
     int fd;
    struct video_capability  capability;
    struct video_buffer  buffer; 
    struct video_picture  picture; 
    struct video_mmap  map;   
    struct video_mbuf  mbuf;       
    //unsigned short *pmap;
    unsigned char  *pmap;
    int frame_current;//what 's the frame number being captured currently?
    int frame_using[VIDEO_MAX_FRAME];//帧的状态没有采集还是等待结束?
    int screensize;

};

MyWidget::MyWidget( QWidget *parent, const char *name )
        : QWidget( parent, name )

  dep=16;
  pal=VIDEO_PALETTE_RGB565;
  width=320;
  height=240;

  frame_current = 0;
  frame_using[0] = 0;
  frame_using[1] = 0;
 
  setCaption("MyJob");
  frame=new QFrame(this,"frame");
  frame->setBackgroundColor(black);
  frame->setGeometry(QRect(40,40,402,252));
  QTimer *timer=new QTimer(this,"timer");
  timer = new QTimer(this);
  connect(timer, SIGNAL(timeout()), SLOT(update()));
  timer->start(30);
  //QTimer::singleShot(50,this,SLOT(update()));
  printf("timer is using\n");

}

int MyWidget::get_grab_frame()
{
 
  if (frame_using[frame_current]) {
      fprintf(stderr, "get_grab_frame: frame %d is already used.\n", frame_current);
      return ERR_FRAME_USING;
  }

  map.frame = frame_current;
  /**
    Start Picture capture from this moment
  */
  if (ioctl(fd, VIDIOCMCAPTURE, &(map)) < 0) {
      perror("v4l_grab_frame");
      return ERR_GET_FRAME;
  }
  //置为采集忙状态
  frame_using[frame_current] = 1;
 
  if (ioctl(fd, VIDIOCSYNC, &(frame_current)) < 0) // 等待帧同步
  { 
      perror("v4l_grab_sync");
      return ERR_SYNC;
  }
  frame_using[frame_current] = 0 ;//采集完毕置0
  //return RIGHT_GRAP_FRAME;

}
int MyWidget::open_video()
{
  // 打开视频设备
      if ((fd = open(V4L_FILE, O_RDWR)) < 0)
  {
      perror("v4l_open:");
      return ERR_VIDEO_OPEN;
  }
    printf("=============Open Video Success=======================");
   
  // 获取设备
  if (ioctl(fd, VIDIOCGCAP, &(capability)) < 0)
  {
      perror("v4l_get_capability:");
      return ERR_VIDEO_GCAP;
  }
  printf("Camera found: %s,maxwidth:%d,maxheight:%d,minwidth:%d,minheight:%d \n",capability.name,capability.maxwidth,capability.maxheight,capability.minwidth,capability.minheight);

  printf("=============Get Device Success=======================");
  // 获取图象
  if (ioctl(fd, VIDIOCGPICT, &(picture)) < 0)
  {
      perror("v4l_get_picture");
      return ERR_VIDEO_GPIC;
  }
      printf("=============Get Picture Success=======================");
     printf("=====Capture depth:%d,Palette:%d,brightness:%d,hue:%d,contrast:%d===============\n",picture.depth,picture.palette,picture.brightness,picture.hue,picture.contrast);
  // 设置图象
  picture.palette = pal;  // 调色板
  picture.depth = dep;  // 像素深度

  map.format =pal;
  if (ioctl(fd, VIDIOCSPICT, &(picture)) < 0)
  {
      perror("v4l_set_palette");
      return ERR_VIDEO_SPIC;
  }
  printf("=====Capture depth:%d,Palette:%d,brightness:%d,hue:%d,contrast:%d===============\n",picture.depth,picture.palette,picture.brightness,picture.hue,picture.contrast);
  //
  /*vd->map.width = width;  // width;
  vd->map.height = height;  // height;
  vd->map.format = vd->picture.palette;*/

  /*frame_current = 0;
  frame_using[0] = 0;
  frame_using[1] = 0;*/
 
  memset (&(mbuf), 0, sizeof(mbuf));
  // 获取摄像头缓冲区信息
  if (ioctl(fd, VIDIOCGMBUF, &(mbuf)) < 0)
  {
      perror("v4l_get_mbuf");
      return -1;
  }
  printf ("VIDIOCGMBUF size %d  frames %d  offets[0]=%d offsets[1]=%d\n",mbuf.size, mbuf.frames, mbuf.offsets[0], mbuf.offsets[1]);
  // 建立设备内存影射,将视频设备影射到内存空间
  pmap = (unsigned char *)mmap(0, mbuf.size, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);
  if ( pmap < 0)
  {
      perror("v4l_mmap_init:map");
      return -1;
  }
  map.width = width;  // width;
  map.height = height;  // height;
  map.format = picture.palette;
  printf("The video device was opened successfully.\n");
}

/*void MyWidget::get_image()
{
  //open_video();                                       
  imageptr = (unsigned short *)(pmap + mbuf.offsets[frame_current]);
  printf("imageptr is 0x%x",imageptr);
/*err:
if(vd.fbfd)
  close(vd.fbfd);    // 关闭FrameBuffer设备

if(vd.fd)
  close(vd.fd);
exit(0);
return 0;*/

//}*/
void MyWidget::paintEvent(QPaintEvent *)
{
    int x, y;
    int i = 0;
    QRgb *point;
    int r, g, b;
    int imgwidth=402;
    int imgheight=252;
    //创建该PaintEvent的操作对象paint
        //该对象为静态对象,不需要每次paint都创建一个QPainter
    static QPainter paint(frame);
         //读取内存内容,创建QImage对象
    QImage *image = new QImage();

    //该步很重要,设置标志
    //让QWidget在更新窗体时,不擦除原来的窗体
    //这样可以避免闪屏
    setWFlags(getWFlags() | Qt::WRepaintNoErase);
   
    //begin graping picture
    get_grab_frame();
    imageptr = (unsigned short *)(pmap + mbuf.offsets[frame_current]);
    //printf("imageptr is 0x%x",imageptr);
   
    frame_current ^= 1;//两帧采集不是0就是1

    if(image->create(imgwidth, imgheight, 32, 0, QImage::IgnoreEndian))
    {
        for(x = 0; x < imgheight; x++)
        {
            for(y = 0; y < imgwidth; y++)
            {
                r = (imageptr&0xf800)>>11;
                g = (imageptr&0x07e0)>>5;
                b = imageptr&0x001f;
                point = (QRgb *)image->scanLine(x)+y;
                *point = qRgb(r, g, b);
                i++;
               
            }
        }
    }

    //开始绘图 
    //paint.drawImage(0, 0, *image);
    paint.drawImage(QRect(40,34,402,252), *image);
    //printf("imageptr[0] is 0x%x",imageptr[0]);
    // paint.end();

    //释放空间
  /* if(vd->mbuf.size)
    {
        munmap(imageptr,vd->mbuf.size);
    }
    else if(imageptr)
    {
        free(imageptr);
    }
    delete image;
    image = NULL;*/
}

int main( int argc, char **argv )
{
    QApplication a( argc, argv );

    MyWidget *w=new MyWidget(0);
    w->setGeometry( 10, 20, 480, 320 );
    a.setMainWidget( w );
    w->show();
    w->open_video();
    //a.connect( &a, SIGNAL( lastWindowClosed() ), &a, SLOT( quit() ) );
    return a.exec();
}
离线txf1949

只看该作者 6楼 发表于: 2008-04-14
我的qq号:522369449  mail:txf1949@126.com  欢迎交流指正!!
快速回复
限100 字节
 
上一个 下一个