跪求大神Qt5.8+V4L2实现USB摄像头实时显示界面!!!!非常急

mazhida_hebut 2017-11-30 05:41:57
跪求大神Qt5.8+V4L2实现USB摄像头实时显示界面!!!!非常急

liunx平台
...全文
357 1 点赞 打赏 收藏 举报
写回复
1 条回复
切换为时间正序
当前发帖距今超过3年,不再开放新的回复
发表回复
qq_39387402 2019-07-02
#include <unistd.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <stdio.h> #include <sys/ioctl.h> #include <stdlib.h> #include <sys/mman.h> #include <linux/types.h> #include <linux/videodev2.h> #include "v4l2grab.h" #define TRUE 1 #define FALSE 0 #define VIDEO_DEV "/dev/video0" #define BMP "image_bmp.bmp" #define YUV "image_yuv.yuv" #define IMAGE_WIDTH 1280 #define IMAGE_HEIGHT 720 static int fd; static struct v4l2_capability cap; struct v4l2_fmtdesc fmtdesc; struct v4l2_format fmt,fmtack; struct v4l2_streamparm setfps; struct v4l2_requestbuffers req; struct v4l2_buffer buf; enum v4l2_buf_type type; unsigned char frame_buffer[IMAGE_WIDTH*IMAGE_HEIGHT*3]; struct buffer { void * start; unsigned int length; } * buffers; int init_v4l2(void) { int i; int ret = 0; //open video if ((fd = open(VIDEO_DEV, O_RDWR)) == -1) { printf("Error opening V4L interface\n"); return (FALSE); } //query cap if (ioctl(fd, VIDIOC_QUERYCAP, &cap) == -1) { printf("Error opening device %s: unable to query device.\n",VIDEO_DEV); return (FALSE); } else { printf("driver:\t\t%s\n",cap.driver); printf("card:\t\t%s\n",cap.card); printf("bus_info:\t%s\n",cap.bus_info); printf("version:\t%d\n",cap.version); printf("capabilities:\t%x\n",cap.capabilities); if ((cap.capabilities & V4L2_CAP_VIDEO_CAPTURE) == V4L2_CAP_VIDEO_CAPTURE) { printf("Device %s: supports capture.\n",VIDEO_DEV); } if ((cap.capabilities & V4L2_CAP_STREAMING) == V4L2_CAP_STREAMING) { printf("Device %s: supports streaming.\n",VIDEO_DEV); } } //emu all support fmt fmtdesc.index=0; fmtdesc.type=V4L2_BUF_TYPE_VIDEO_CAPTURE; printf("Support format:\n"); while(ioctl(fd,VIDIOC_ENUM_FMT,&fmtdesc)!=-1) { printf("\t%d.%s\n",fmtdesc.index+1,fmtdesc.description); fmtdesc.index++; } //set fmt fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; fmt.fmt.pix.pixelformat = V4L2_PIX_FMT_YUYV; fmt.fmt.pix.height = IMAGE_HEIGHT; fmt.fmt.pix.width = IMAGE_WIDTH; fmt.fmt.pix.field = V4L2_FIELD_INTERLACED; if(ioctl(fd, VIDIOC_S_FMT, &fmt) == -1) { printf("Unable to set format\n"); return FALSE; } if(ioctl(fd, VIDIOC_G_FMT, &fmt) == -1) { printf("Unable to get format\n"); return FALSE; } { printf("fmt.type:\t\t%d\n",fmt.type); printf("pix.pixelformat:\t%c%c%c%c\n",fmt.fmt.pix.pixelformat & 0xFF, (fmt.fmt.pix.pixelformat >> 8) & 0xFF,(fmt.fmt.pix.pixelformat >> 16) & 0xFF, (fmt.fmt.pix.pixelformat >> 24) & 0xFF); printf("pix.height:\t\t%d\n",fmt.fmt.pix.height); printf("pix.width:\t\t%d\n",fmt.fmt.pix.width); printf("pix.field:\t\t%d\n",fmt.fmt.pix.field); } printf("init %s \t[OK]\n",VIDEO_DEV); return TRUE; } int v4l2_grab(void) { unsigned int n_buffers; //request for 4 buffers req.count=4; req.type=V4L2_BUF_TYPE_VIDEO_CAPTURE; req.memory=V4L2_MEMORY_MMAP; if(ioctl(fd,VIDIOC_REQBUFS,&req)==-1) { printf("request for buffers error\n"); } //mmap for buffers buffers = malloc(req.count*sizeof (*buffers)); if (!buffers) { printf ("Out of memory\n"); return(FALSE); } for (n_buffers = 0; n_buffers < req.count; n_buffers++) { buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; buf.memory = V4L2_MEMORY_MMAP; buf.index = n_buffers; //query buffers if (ioctl (fd, VIDIOC_QUERYBUF, &buf) == -1) { printf("query buffer error\n"); return(FALSE); } buffers[n_buffers].length = buf.length; //map buffers[n_buffers].start = mmap(NULL,buf.length,PROT_READ |PROT_WRITE, MAP_SHARED, fd, buf.m.offset); if (buffers[n_buffers].start == MAP_FAILED) { printf("buffer map error\n"); return(FALSE); } } //queue for (n_buffers = 0; n_buffers < req.count; n_buffers++) { buf.index = n_buffers; ioctl(fd, VIDIOC_QBUF, &buf); } type = V4L2_BUF_TYPE_VIDEO_CAPTURE; ioctl (fd, VIDIOC_STREAMON, &type); ioctl(fd, VIDIOC_DQBUF, &buf); printf("grab yuyv OK\n"); return(TRUE); } int yuyv_2_rgb888(unsigned char *yuv, unsigned char *rgb, int width, int height) { int i,j; unsigned char y1,y2,u,v; int r1,g1,b1,r2,g2,b2; char * pointer; pointer = yuv; width /=2; for(i=0;i<height;i++) { for(j=0;j<width;j++) { y1 = *( pointer + (i*width+j)*4); u = *( pointer + (i*width+j)*4 + 1); y2 = *( pointer + (i*width+j)*4 + 2); v = *( pointer + (i*width+j)*4 + 3); r1 = y1 + 1.042*(v-128); g1 = y1 - 0.34414*(u-128) - 0.71414*(v-128); b1 = y1 + 1.772*(u-128); r2 = y2 + 1.042*(v-128); g2 = y2 - 0.34414*(u-128) - 0.71414*(v-128); b2 = y2 + 1.772*(u-128); if(r1>255) r1 = 255; else if(r1<0) r1 = 0; if(b1>255) b1 = 255; else if(b1<0) b1 = 0; if(g1>255) g1 = 255; else if(g1<0) g1 = 0; if(r2>255) r2 = 255; else if(r2<0) r2 = 0; if(b2>255) b2 = 255; else if(b2<0) b2 = 0; if(g2>255) g2 = 255; else if(g2<0) g2 = 0; *(rgb + ((height-1-i)*width+j)*6 ) = (unsigned char)b1; *(rgb + ((height-1-i)*width+j)*6 + 1) = (unsigned char)g1; *(rgb + ((height-1-i)*width+j)*6 + 2) = (unsigned char)r1; *(rgb + ((height-1-i)*width+j)*6 + 3) = (unsigned char)b2; *(rgb + ((height-1-i)*width+j)*6 + 4) = (unsigned char)g2; *(rgb + ((height-1-i)*width+j)*6 + 5) = (unsigned char)r2; } } printf("change to RGB OK \n"); } int close_v4l2(void) { if(fd != -1) { close(fd); return (TRUE); } return (FALSE); } int main(void) { FILE * fp1,* fp2; BITMAPFILEHEADER bf; BITMAPINFOHEADER bi; fp1 = fopen(BMP, "wb"); if(!fp1) { printf("open "BMP"error\n"); return(FALSE); } fp2 = fopen(YUV, "wb"); if(!fp2) { printf("open "YUV"error\n"); return(FALSE); } if(init_v4l2() == FALSE) { return(FALSE); } //Set BITMAPINFOHEADER bi.biSize = 40; bi.biWidth = IMAGE_WIDTH; bi.biHeight = IMAGE_HEIGHT; bi.biPlanes = 1; bi.biBitCount = 24; bi.biCompression = 0; bi.biSizeImage = IMAGE_WIDTH*IMAGE_HEIGHT*3; bi.biXPelsPerMeter = 0; bi.biYPelsPerMeter = 0; bi.biClrUsed = 0; bi.biClrImportant = 0; //Set BITMAPFILEHEADER bf.bfType = 0x4d42; bf.bfSize = 54 + bi.biSizeImage; bf.bfReserved = 0; bf.bfOffBits = 54; v4l2_grab(); fwrite(buffers[0].start, buffers[0].length, 1, fp2); printf("save yuv OK\n"); yuyv_2_rgb888(buffers[0].start, frame_buffer, IMAGE_WIDTH, IMAGE_HEIGHT); fwrite(&bf, 14, 1, fp1); fwrite(&bi, 40, 1, fp1); fwrite(frame_buffer, bi.biSizeImage, 1, fp1); printf("save "BMP"OK\n"); fclose(fp1); fclose(fp2); close_v4l2(); return(TRUE); } /****************************************************/ /* */ /* v4lgrab.h */ /* */ /****************************************************/ #ifndef __V4LGRAB_H__ #define __V4LGRAB_H__ #include <stdio.h> //typedef enum { FALSE = 0, TRUE = 1, OK = 2} BOOL; //#define SWAP_HL_WORD(x) {(x) = ((x)<<8) | ((x)>>8);} //#define SWAP_HL_DWORD(x) {(x) = ((x)<<24) | ((x)>>24) | (((x)&0xff0000)>>8) | (((x)&0xff00)<<8);} #define FREE(x) if((x)){free((x));(x)=NULL;} typedef unsigned char BYTE; typedef unsigned short WORD; typedef unsigned long DWORD; /**/ #pragma pack(1) typedef struct tagBITMAPFILEHEADER{ WORD bfType; // the flag of bmp, value is "BM" DWORD bfSize; // size BMP file ,unit is bytes DWORD bfReserved; // 0 DWORD bfOffBits; // must be 54 }BITMAPFILEHEADER; typedef struct tagBITMAPINFOHEADER{ DWORD biSize; // must be 0x28 DWORD biWidth; // DWORD biHeight; // WORD biPlanes; // must be 1 WORD biBitCount; // DWORD biCompression; // DWORD biSizeImage; // DWORD biXPelsPerMeter; // DWORD biYPelsPerMeter; // DWORD biClrUsed; // DWORD biClrImportant; // }BITMAPINFOHEADER; typedef struct tagRGBQUAD{ BYTE rgbBlue; BYTE rgbGreen; BYTE rgbRed; BYTE rgbReserved; }RGBQUAD; #if defined(__cplusplus) extern "C" { /* Make sure we have C-declarations in C++ programs */ #endif //if successful return 1,or else return 0 int openVideo(); int closeVideo(); //data 用来存储数据的空间, size空间大小 void getVideoData(unsigned char *data, int size); #if defined(__cplusplus) } #endif #endif //__V4LGRAB_H___
  • 打赏
  • 举报
回复
相关推荐
发帖
Linux/Unix社区
加入

2.1w+

社区成员

Linux/Unix社区 应用程序开发区
申请成为版主
帖子事件
创建了帖子
2017-11-30 05:41
社区公告
暂无公告