USB攝像頭視頻采集與QT界面顯示_第1頁(yè)
USB攝像頭視頻采集與QT界面顯示_第2頁(yè)
USB攝像頭視頻采集與QT界面顯示_第3頁(yè)
USB攝像頭視頻采集與QT界面顯示_第4頁(yè)
USB攝像頭視頻采集與QT界面顯示_第5頁(yè)
已閱讀5頁(yè),還剩9頁(yè)未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說(shuō)明:本文檔由用戶(hù)提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡(jiǎn)介

1、USB攝像頭視頻采集與Qt界面顯示一 Qt界面制作1 新建Qt工程啟動(dòng)Qt Creator,新建一個(gè)Qt Gui應(yīng)用。單擊File選擇New File or Project出現(xiàn)以下界面:選擇Qt Gui Application,之后選擇好工程與路徑名,其他默認(rèn),一直到設(shè)置Class information(類(lèi)信息)時(shí),Class name設(shè)為Widget, Base name選擇QWidget,其他默認(rèn)。設(shè)置好這些后,其他默認(rèn),直到工程設(shè)置結(jié)束。如下圖所示:2. 修改ui界面打開(kāi)Widget.ui,進(jìn)入可視化設(shè)計(jì)界面。默認(rèn)情況中間的主設(shè)計(jì)區(qū)下只有一個(gè)Widget的對(duì)象。由于USB攝像頭采集到的

2、圖像需要顯示到一個(gè)QLabel的部件上,從右側(cè)的部件列表的“DisplayWidget”中選擇“Label”部件拖動(dòng)到中間;此外,我們需要兩個(gè)按鈕,一個(gè)用于啟動(dòng)和終止視頻數(shù)據(jù)的保存,一個(gè)用于以后的視頻文件的壓縮。從右側(cè)的”Buttons”中兩次選擇”P(pán)ush Buttion”部件并拖動(dòng)到Widget中。從上圖可以看出,對(duì)象Widget下已經(jīng)添加了一個(gè)label部件,兩個(gè)push button部件。右上角Object與Class的關(guān)系是:Object對(duì)應(yīng)的物體是屬于Class對(duì)應(yīng)的類(lèi),反映了Qt的繼承關(guān)系。接下來(lái)設(shè)置上面四種部件的屬性,Widget的屬性按照下面圖示設(shè)置,其中g(shù)eometry設(shè)置

3、為(0,0),650*550說(shuō)明界面左上角的坐標(biāo)位于原點(diǎn),大小為650*550;在window name這一項(xiàng)設(shè)置的是你的界面的名字,我設(shè)置為USB_YUV_Camera。注:圖片未提及的采用默認(rèn)就行,其他三個(gè)部件見(jiàn)圖示。這些部件的objectName要特別注意,因?yàn)闀?huì)在后面編寫(xiě)的程序中用到。 (Widget設(shè)置圖示) (label設(shè)置圖示1) (label設(shè)置圖示2) (Push button 1設(shè)置圖示) (Push button 1設(shè)置圖示) (Push button 2設(shè)置圖示) Push button 2設(shè)置圖示)最后生成的界面:點(diǎn)擊Debug會(huì)得到Debug文檔,里面有你設(shè)置的信息

4、。編譯運(yùn)行后,會(huì)在建立的工程文件夾下生成很多文件,重要的是widget.ui文件,其他的文件要根據(jù)你具體的應(yīng)用作出相應(yīng)的修改。Qt界面最終的效果圖為:二 USB攝像頭視頻采集與Qt界面顯示源代碼分析源碼包含:common.h VideoDevice.h widget.h VideoDevice.cpp widget.cpp main.cppcommon.h主要定義了USB采集到的圖像的寬度,高度等信息;Videodevice.h定義了VideoDevice類(lèi),使它繼承于Qt的基類(lèi)QObject,定義了VideoDevice的構(gòu)造函數(shù)與析構(gòu)函數(shù),重要的是定義了實(shí)現(xiàn)V4L2視頻架構(gòu)的函數(shù);Vide

5、odevice.cpp具體實(shí)現(xiàn)了Videodevice.h定義的函數(shù),完成了基于V4L2架構(gòu)的視頻采集;widget.h定義了Widget窗口類(lèi),使它繼承于Qt窗口類(lèi)QWidget,并定義了YUV到RGB顏色轉(zhuǎn)變的函數(shù);QT界面按鈕操作的實(shí)現(xiàn)函數(shù),以及視頻窗口的刷新時(shí)間painEvent函數(shù);widget.cpp實(shí)現(xiàn)了widget.h定義的函數(shù)。下面介紹各文件的主要代碼段:(1)common.h#ifndef COMMON_H#define COMMON_H/ #define IMG_WIDTH 640/定義視頻的寬度為640#define IMG_HEIGTH 480/定義視頻的高度為480

6、#endif / COMMON_H(2) Videodevice.h#define CLEAR(x) memset(&(x), 0, sizeof(x)/定義CLEAR為內(nèi)存清零class VideoDevice : public QObject Q_OBJECT /有了這條語(yǔ)句才能使用QT中的signal和slot機(jī)制public: VideoDevice(QString dev_name);/構(gòu)造函數(shù)定義,用于初始化 VideoDevice();/析構(gòu)函數(shù)用于釋放內(nèi)存 int get_frame(unsigned char * yuv_buffer_pointer, size_t*

7、 len);/獲取視頻幀 int unget_frame();/釋放視頻幀,讓出緩存空間準(zhǔn)備新的視頻幀數(shù)據(jù)private: int open_device();/打開(kāi)設(shè)備 int init_device();/初始化設(shè)備 int start_capturing();/啟動(dòng)視頻采集 int init_mmap();/內(nèi)存映射初始化 int stop_capturing();/停止視頻采集 int uninit_device();/注銷(xiāo)設(shè)備 int close_device();/關(guān)閉設(shè)備 struct buffer void * start;/視頻緩沖區(qū)的起始地址 size_t length;/

8、緩沖區(qū)的長(zhǎng)度 ; QString dev_name; int fd;/video0 file buffer* buffers; unsigned int n_buffers; int index;signals: /void display_error(QString);#endif / VIDEODEVICE_H(3)Videodevice.cpp#define FILE_VIDEO "/dev/video0"VideoDevice:VideoDevice(QString dev_name)/VideoDevice的構(gòu)造函數(shù)進(jìn)行初始化 this->dev_name

9、= dev_name; this->fd = -1; this->buffers = NULL; this->n_buffers = 0; this->index = -1; if(open_device() = FALSE) close_device(); if(init_device() = FALSE) close_device(); if(start_capturing() = FALSE) stop_capturing(); close_device(); VideoDevice:VideoDevice()/VideoDevice的析構(gòu)函數(shù) if(stop_c

10、apturing() = FALSE) if(uninit_device() = FALSE) if(close_device() = FALSE) int VideoDevice:init_device()/設(shè)備初始化 v4l2_capability cap;/設(shè)備能力結(jié)構(gòu)體 v4l2_format fmt;/設(shè)置視頻像素 v4l2_streamparm setfps;/設(shè)置采樣率v4l2_fmtdesc fmtdesc;/查詢(xún)攝像頭支持像素格式 if(ioctl(fd, VIDIOC_QUERYCAP, &cap) = -1) printf("Error opening

11、device %s: unable to query device.n",FILE_VIDEO); return FALSE; else printf("driver:tt%sn",cap.driver);/驅(qū)動(dòng)名 printf("card:tt%sn",cap.card);/攝像頭信息 printf("bus_info:t%sn",cap.bus_info);/PCI總線信息 printf("version:t%dn",cap.version);/內(nèi)核版本 printf("capabili t

12、ies:t%xn",cap.capabilities);/以上打印信息詳見(jiàn)設(shè)備能力結(jié)構(gòu)體(struct v4l2_capability) if (cap.capabilities & V4L2_CAP_VIDEO_CAPTURE) printf("Device %s: supports capture.n",FILE_VIDEO); if (cap.capabilities & V4L2_CAP_STREAMING) printf("Device %s: supports streaming.n",FILE_VIDEO); /列

13、舉攝像頭所支持像素格式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.%sn",fmtdesc.index+1,fmtdesc.description);fmtdesc.index+; /set fmt fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;/恒為此項(xiàng) fmt.fmt.pix.

14、pixelformat = V4L2_PIX_FMT_YUYV;/視頻數(shù)據(jù)存儲(chǔ)類(lèi)型 fmt.fmt.pix.height = 480; fmt.fmt.pix.width = 640; fmt.fmt.pix.field = V4L2_FIELD_INTERLACED;/隔行掃描 if(ioctl(fd, VIDIOC_S_FMT, &fmt) = -1) printf("Unable to set formatn"); return FALSE; if(ioctl(fd, VIDIOC_G_FMT, &fmt) = -1) printf("Una

15、ble to get formatn"); return FALSE; /set fps 具體參考結(jié)構(gòu)體v4l2_captureparm setfps.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;/*timeperframe字段用于指定想要使用的幀頻率,它是一個(gè)結(jié)構(gòu)體:numerator 和denominator所描述的系數(shù)給出的是成功的幀之間的時(shí)間間隔。numerator分子,denominator分母。主要表達(dá)每次幀之間時(shí)間間隔。numerator/denominator秒一幀。*/ setfps.parm.capture.timeperframe.nu

16、merator = 1; setfps.parm.capture.timeperframe.denominator = 30;/本攝像頭幀頻范圍5,30幀/秒 if(ioctl(fd, VIDIOC_S_PARM, &setfps) = -1) printf("Unable to set frame raten"); return FALSE; else printf("set fps OK!n"); if(ioctl(fd, VIDIOC_G_PARM, &setfps) = -1) printf("Unable to get

17、 frame raten"); return FALSE; else printf("get fps OK!n"); printf("timeperframe.numerator:t%dn",setfps.parm.capture.timeperframe.numerator); printf("timeperframe.denominator:t%dn",setfps.parm.capture.timeperframe.denominator); /mmap if(init_mmap() = FALSE ) printf(

18、"cannot mmap!n"); return FALSE; return TRUE;(4)widget.h namespace Ui class Widget;class Widget : public QWidget Q_OBJECT /上面內(nèi)容為固定格式public: explicit Widget(QWidget *parent = 0);/explicit可以避免發(fā)生隱式類(lèi)型轉(zhuǎn)換 Widget();private: Ui:Widget *ui; QImage *frame; int rs; unsigned int len; int convert_yuv_to

19、_rgb_buffer(); void print_quartet(unsigned int i); VideoDevice *vd; FILE * yuvfile; unsigned char rgb_buffer640*480*3; unsigned char * yuv_buffer_pointer; char Y_frame640*480;/存儲(chǔ)亮度Y分量 char Cr_frame240*320; /存儲(chǔ)藍(lán)色濃度偏移量即U分量 char Cb_frame240*320; /存儲(chǔ)紅色濃度偏移量即V分量 int write420();/視頻圖像保存為YUV420,也可存儲(chǔ)為YUV422p

20、rivate slots:/定義槽 void on_pushButton_start_clicked();/按鈕按下對(duì)應(yīng)的處理,不定義成槽,按鈕將失效 void paintEvent(QPaintEvent *);/窗口刷新函數(shù);#endif / WIDGET_H(5) widget.cppchar yuvfilename11 = 's','a','v','e','0','0','.','y','u','v','0'/視

21、頻保存文件的名稱(chēng)Widget:Widget(QWidget *parent) : QWidget(parent), ui(new Ui:Widget) ui->setupUi(this); vd = new VideoDevice(tr("/dev/video0");frame = new QImage(rgb_buffer,640,480,QImage:Format_RGB888);void Widget:paintEvent(QPaintEvent *) rs = vd->get_frame(&yuv_buffer_pointer,&len)

22、;if(last_state=2 && state = 0) yuvfile = fopen(yuvfilename,"wb+"); yuvfilename5+; if(state = 1) rs = write420(); if(last_state=1 && state=2) fclose(yuvfile);int Widget:write420() int x,y; long int index1 =0; if (yuv_buffer_pointer0 = '0') return -1; for(x=0;x<640

23、;x+) for(y=0;y<480;y+) Y_frameindex1=yuv_buffer_pointer2*index1; index1+; index1=0; for(x=0;x<480;x+,x+) for(y=0;y<640;y+,y+) Cb_frameindex1=yuv_buffer_pointer(x*640+y)*2+1; Cr_frameindex1=yuv_buffer_pointer(x*640+y)*2+3; index1+; /YUV422的程序/* for(x=0;x<480;x+) for(y=0;y<320;y+)Y_fram

24、eindex= yuv_buffer_pointer(x*320+y)*4;Cb_frameindex= yuv_buffer_pointer(x*320+y)*4 + 1;Y_frameindex+1= yuv_buffer_pointer(x*320+y)*4 + 2;Cr_frameindex= yuv_buffer_pointer (x*320+y)*4 + 3;index+;*/ fwrite(Y_frame, 307200, 1, yuvfile); fwrite(Cb_frame,76800, 1, yuvfile); fwrite(Cr_frame,76800, 1, yuvf

25、ile); framecnt+; printf("writed frame %ldn",framecnt);int Widget:convert_yuv_to_rgb_buffer() unsigned long in, out = 0; int y0, u, y1, v; int r, g, b; for(in = 0; in < IMG_WIDTH * IMG_HEIGTH * 2; in += 4) y0 = yuv_buffer_pointerin + 0; u = yuv_buffer_pointerin + 1; y1 = yuv_buffer_point

26、erin + 2; v = yuv_buffer_pointerin + 3; r = y0 + (1.370705 * (v-128); g = y0 - (0.698001 * (v-128) - (0.337633 * (u-128); b = y0 + (1.732446 * (u-128);/*r = y0 + 1.042*(v-128); g = y0 - 0.34414*(u-128) - 0.71414*(v-128); b = y0 + 1.772*(u-128);*/ / YUV422程序 if(r > 255) r = 255; if(g > 255) g = 255; if(b > 255) b = 255; if(r < 0) r = 0; if(g < 0) g = 0; if(b < 0) b = 0; rgb_bufferout+ = r; rgb_bufferout+ = g; rgb_bufferout+ = b; r = y1 + (1.370705 * (v-128); g = y1 - (0.698001 * (v-128) - (0.337633 * (u-128); b = y1 + (1.73244

溫馨提示

  • 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶(hù)所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶(hù)上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶(hù)上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶(hù)因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

最新文檔

評(píng)論

0/150

提交評(píng)論