VC捕捉攝像頭圖像入門源碼要點(diǎn)_第1頁
VC捕捉攝像頭圖像入門源碼要點(diǎn)_第2頁
VC捕捉攝像頭圖像入門源碼要點(diǎn)_第3頁
VC捕捉攝像頭圖像入門源碼要點(diǎn)_第4頁
VC捕捉攝像頭圖像入門源碼要點(diǎn)_第5頁
已閱讀5頁,還剩11頁未讀 繼續(xù)免費(fèi)閱讀

下載本文檔

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

文檔簡介

1、【轉(zhuǎn)】vc捕捉攝像頭圖像入門源碼vc捕捉攝像頭圖像入門源碼(非常適合新手)(轉(zhuǎn))默認(rèn)分類2009-11-02 17:46:56 閱讀39評(píng)論0字號(hào):大中 小此源碼是我更改過的基于 vfw(video for windows)的源碼,使用了定時(shí)器能 實(shí)時(shí)的顯示圖像,從網(wǎng)上可搜到原版源碼,但是原版的功能是保存為一個(gè)文件, 且不能實(shí)時(shí)顯示,此版本雖然能顯示,但感覺反應(yīng)速度不是很快,沒有基于 directshow的程序更新速度快,不過在 wm_paint息處理里加while(1)capgrabframe(ghwndcap);刷新速度就快很多了,但是這樣程序就進(jìn) 入死循環(huán)不能再處理其他消息,至于怎樣改進(jìn)

2、,就靠讀者你了。/源碼的任何部分都可以在 msdn!查至ij,請(qǐng)參考 msdn#include <windows.h>#include <stdio.h>#include <vfw.h>#pragma comment(lib,"vfw32.lib")hwnd ghwndcap ; /f甫獲窗的句柄capstatus gcapstatus ; / 捕獲窗的狀態(tài)capdrivercaps gcapdrivercaps ; 視頻驅(qū)動(dòng)的能力 char gachbuffer20;/char szcapturefile口 = "camcap

3、ture.avi"/ / statuscallbackproc: 冊(cè)這個(gè)回調(diào)函數(shù)。/ hwnd:/ nid:/ lpstatustext:狀態(tài)回調(diào)函數(shù),使用capsetcallbackonstatus 宏來注捕獲窗體句柄當(dāng)前狀態(tài)的狀態(tài)碼 當(dāng)前狀態(tài)的文本字符/lresult callback statuscallbackproc(hwnd hwnd,int nid,lpstr lpstatustext)if(!ghwndcap)return false;/獲得捕獲窗的狀態(tài)capgetstatus(ghwndcap,&gcapstatus,sizeof(capstatus);/

4、更新捕獲窗的大小 , 得到消息 wm_cap_get_statussetwindowpos(ghwndcap,null,0,0,gcapstatus.uiimagewidth,gcapstatus.uii mageheight,swp_nozorder|swp_nomove);if(nid=0)/ 清除舊的狀態(tài)信息setwindowtext(ghwndcap,(lpstr)"hello");return (lresult)true;/ 顯示狀態(tài) id 和狀態(tài)文本wsprintf(gachbuffer,"status# %d: %s",nid,lpstat

5、ustext);setwindowtext(ghwndcap,(lpstr)gachbuffer);return (lresult)true;/ errorcallbackproc:錯(cuò)誤回調(diào)函數(shù), 過 capsetcallbackonerror 宏來 注冊(cè)回調(diào)捕獲窗口句柄錯(cuò)誤代碼關(guān)于錯(cuò)誤的文本信息/ hwnd:/ nerrid: / lperrortext: /lresult callback errorcallbackproc(hwnd hwnd,int nerrid,lpstr lperrortext)if(!ghwndcap)return false;if(nerrid=0)return

6、 true;/ 清除舊的錯(cuò)誤wsprintf(gachbuffer,"error# %d",nerrid);/ 顯示錯(cuò)誤標(biāo)識(shí)和文本messagebox(hwnd, lperrortext, gachbuffer,mb_ok | mb_iconexclamation); return (lresult) true;/ framecallbackproc: 幀回調(diào)函數(shù), 通過 capsetcallbackframe 宏來注冊(cè)捕獲窗體句柄指向一個(gè)包含幀信息的數(shù)據(jù)結(jié)構(gòu)體回調(diào)函數(shù)/ hwnd:/ lpvhdr: / /lresult callback framecallbackpro

7、c(hwnd hwnd,lpvideohdr lpvhdr) file *fp;fp=fopen("caram.dat","w");if(!ghwndcap)return false;/ 假設(shè) fp 為一打開的 .dat 文件指針fwrite(lpvhdr->lpdata,1,lpvhdr->dwbufferlength,fp); return (lresult)true;/ /timerproc 函數(shù)處理定時(shí)器,在這里抓取并顯示圖像/void callback timerproc(hwnd hwnd,/ handle to windowui

8、nt umsg,/ wm_timer messageuint_ptr idevent, / timer identifierdword dwtime/ current system time)capgrabframe(ghwndcap);/ 主回調(diào)函數(shù)/lresult callback windowproc(hwnd hwnd,/ handle to windowuint umsg,/ message identifierwparam wparam, / first message parameter lparam lparam / second message parameter )/ hd

9、c hdc;/ paintstruct ps;/ rect rect;switch(umsg)case wm_create:ghwndcap=capcreatecapturewindow(lpstr)"capture window",ws_child|ws_visible,0,0,320,240,(hwnd)hwnd,(int)0);capsetcallbackonerror(ghwndcap,(farproc)errorcallbackproc);capsetcallbackonstatus(ghwndcap,(farproc)statuscallbackproc); c

10、apsetcallbackonframe(ghwndcap,(farproc)framecallbackproc);capdriverconnect(ghwndcap,0); / 將捕獲窗同驅(qū)動(dòng)連接capdrivergetcaps(ghwndcap,&gcapdrivercaps,sizeof(capdrivercaps);/ 獲得驅(qū)動(dòng)的能力 , 相關(guān)的信息放在結(jié)構(gòu)變量gcapdrivercaps 中cappreviewrate(ghwndcap, 66); /uses this macro to set the framedisplay rate for preview mode t

11、o 66 milliseconds per framecappreview(ghwndcap, true); /and then uses the cappreview macro to place the capture window in preview mode.if(gcapdrivercaps.fhasoverlay) / 檢查驅(qū)動(dòng)器是否有疊加能力capoverlay(ghwndcap,true); / 啟動(dòng) overlay 模式if(gcapdrivercaps.fhasdlgvideosource)capdlgvideosource(ghwndcap);/video source

12、 對(duì)話框if(gcapdrivercaps.fhasdlgvideoformat)capdlgvideoformat(ghwndcap);/ video format 對(duì)話框if(gcapdrivercaps.fhasdlgvideodisplay)capdlgvideodisplay(ghwndcap); / video display 對(duì)話框/ capfilesetcapturefile( ghwndcap,szcapturefile); / 將要保存的文件名設(shè)為本源文件開頭處的全局字符串常量/ capfilealloc(ghwndcap, (1024l * 1024l * 5); / 為

13、捕獲文件分配存儲(chǔ)空間capcapturesequence(ghwndcap); / 開始捕獲視頻序列/ capgrabframe(ghwndcap); / 捕獲單幀圖像settimer(hwnd,1,10,timerproc);break;case wm_paint:capgrabframe(ghwndcap);/* hdc=beginpaint(hwnd,&ps);getclientrect(hwnd,&rect);drawtext(hdc,text("hello,windowsxp!"),-1,&rect,dt_singleline|dt_cen

14、ter|dt_vcenter);endpaint(hwnd,&ps);*/break;case wm_close: if(idyes=messagebox(hwnd,"sure exit ?","camcapture",mb_yesno) destroywindow(hwnd); break;case wm_destroy:killtimer(hwnd,1);capsetcallbackonstatus(ghwndcap,null); capsetcallbackonerror(ghwndcap,null); capsetcallbackonfr

15、ame(ghwndcap,null); capcaptureabort(ghwndcap);/ 停止捕獲 capdriverdisconnect(ghwndcap); / 將捕獲窗同驅(qū)動(dòng)斷開 postquitmessage(0); break;default:return defwindowproc(hwnd,umsg,wparam,lparam); return 0;/ 主函數(shù)int winapi winmain(hinstance hinstance,/ handle to currentinstancehinstance hprevinstance, / handle to previo

16、us instancelpstr lpcmdline,/ command lineint ncmdshow/ show state) static tchar szappname=text("camcapture"); wndclass wndcls; hwnd hwnd; msg msg;wndcls.cbclsextra=0;wndcls.cbwndextra=0;wndcls.hbrbackground=(hbrush)getstockobject(black_brush); wndcls.hcursor=loadcursor(null,idc_cross); wnd

17、cls.hicon=loadicon(null,idi_question); wndcls.hinstance=hinstance;wndcls.lpfnwndproc=windowproc;wndcls.lpszclassname="camcapture"wndcls.lpszmenuname=null;wndcls.style=cs_hredraw | cs_vredraw;if(!registerclass(&wndcls)messagebox(null,text("this program requires windows nt!"),s

18、zappname,mb_iconerror);return 0;hwnd=createwindow("camcapture","camcapture",ws_overlappedwindow, cw_usedefault,cw_usedefault,320,240,null,null,hinstance,null);showwindow(hwnd,ncmdshow);updatewindow(hwnd);while(getmessage(&msg,null,0,0)translatemessage(&msg);dispatchmessag

19、e(&msg);return 0;摘要: 本文主要講述用 directshow 進(jìn)行視頻捕捉 (捕捉靜態(tài)圖像) 的編程思路,并提供針對(duì)攝像頭編程的一個(gè)視頻捕捉類ccapturevideo 和一個(gè)示例。、戶 、.前言directshow是微軟公司提供的一套在 windows平臺(tái)上進(jìn)行流媒體處理的開發(fā)包,與 directx 開發(fā)包一起發(fā)布。 directshow 為多媒體流的捕捉和回放提供了強(qiáng)有力的支持。用 directshow 開發(fā)應(yīng)用程序,我們可以很方便地從支持wdm驅(qū)動(dòng)模型的采集卡上捕獲數(shù)據(jù),并且進(jìn)行相應(yīng)的后期處理乃至存儲(chǔ)到文件中。directshow是基于com勺,為了編寫 dir

20、ectshow應(yīng)用程序,需要了解 com客戶程序編寫的基礎(chǔ)知識(shí)。 directshow 提供了大量的接口,但在編程中發(fā)現(xiàn)還是不夠方便, 如果能構(gòu)建一個(gè)視頻捕捉類把常用的一些動(dòng)作封裝起來, 那么就更方便了。編程思路為了更加容易建立視頻捕捉應(yīng)用程序, directshow 提供了一個(gè)叫做capturegraph builder 的對(duì)象, capture graph builder 提供 icapturegraphbuilder2 接口,該接口可以建立和控制 capture graph 。建立視頻捕捉程序,必須首先獲取并初始化 icapturegraphbuilder2 接口,然后選擇一個(gè)適當(dāng)?shù)囊曨l

21、捕捉設(shè)備。選擇好設(shè)備后,為該設(shè)備創(chuàng)建capturefilter ,然后調(diào)用 addfilter 把 capture filter 添加到 filter graph 。如果僅僅希望用攝像頭來進(jìn)行實(shí)時(shí)監(jiān)控的話,只需要在上面的基礎(chǔ)上調(diào)用icapturegraphbuilder2:renderstream 就可以了:icapturegraphbuilder2 *pbuild; / capture graph builder/ 省略初始化部分代碼ibasefilter *pcap; / video capture filter./ 省略初始化和添加到 filter graph 部分代碼pbuild-&g

22、t;renderstream(&pin_category_preview, &mediatype_video, pcap, null, null);directshow 提供了一個(gè)捕捉靜態(tài)圖像的方法: 使用 samplegrabber filter 。依次按照以下三個(gè)步驟就可以了:第一步 , 定義一個(gè)類實(shí)現(xiàn)sample grabber 的回調(diào)接口 isamplegrabbercb :class csamplegrabbercb : public isamplegrabbercb / 在后面提供的類中具體完成csamplegrabbercb mcb;第二步、調(diào)用 renderst

23、ream 依次把 still pin 、 sample grabber 和系統(tǒng)默 認(rèn) renderer filter 連接起來。第三步、配置sample grabber 以捕獲數(shù)據(jù)。視頻捕捉類ccapturevideo 的具體實(shí)現(xiàn)/ ccapturevideo 視頻捕捉類頭文件/#if !defined(afx_capturevideo_h_f5345aa4_a39f_4b07_b843_3d87c4287aa0 _included_)#defineafx_capturevideo_h_f5345aa4_a39f_4b07_b843_3d87c4287aa0_included_ / captu

24、revideo.h : header file/#if _msc_ver > 1000#pragma once#endif / _msc_ver > 1000#include <atlbase.h>#include <windows.h>#include <dshow.h>#ifndef safe_release#define safe_release( x ) if ( null != x ) x->release( ); x = null; #endifclass csamplegrabbercb;class ccapturevideo

25、 : public cwndfriend class csamplegrabbercb;public:void graboneframe(bool bgrab);hresult init(int ideviceid,hwnd hwnd);int enumdevices(hwnd hlist);ccapturevideo();virtual ccapturevideo();private:hwnd m_hwnd;igraphbuilder *m_pgb;icapturegraphbuilder2* m_pcapture;ibasefilter* m_pbf;imediacontrol* m_pm

26、c;ivideowindow* m_pvw;ccomptr<isamplegrabber> m_pgrabber;protected:void freemediatype(am_media_type& mt);bool bindfilter(int deviceid, ibasefilter *pfilter);void resizevideowindow();hresult setupvideowindow();hresult initcapturegraphbuilder();#endif/ !defined(afx_capturevideo_h_f5345aa4_a3

27、9f_4b07_b843_3d87c4287aa0_included_)/ ccapturevideo 視頻捕捉類實(shí)現(xiàn)文件 capturevideo.cpp/ capturevideo.cpp: implementation of the ccapturevideo class./#include "stdafx.h"#include "capturevideo.h"#ifdef _debug#undef this_filestatic char this_file=_file_;#define new debug_new#endifbool bones

28、hot=false;/全局變量class csamplegrabbercb : public isamplegrabbercbpublic:long lwidth;long lheight;tchar m_szfilenamemax_path;位圖文件名稱csamplegrabbercb( )strcpy(m_szfilename, "c:donaldo.bmp");stdmethodimp_(ulong) addref() return 2; stdmethodimp_(ulong) release() return 1; stdmethodimp queryinterf

29、ace(refiid riid, void * ppv)if( riid = iid_isamplegrabbercb | riid = iid_iunknown )*ppv = (void *) static_cast<isamplegrabbercb*> ( this );return noerror;return e_nointerface;stdmethodimp samplecb( double sampletime, imediasample * psample ) return 0;stdmethodimp buffercb( double dblsampletime

30、, byte * pbuffer, long lbuffersize )if( !boneshot )return 0;if (!pbuffer)return e_pointer;savebitmap(pbuffer, lbuffersize);boneshot = false;return 0;/ 創(chuàng)建位圖文件bool savebitmap(byte * pbuffer, long lbuffersize )handle hf = createfile(m_szfilename, generic_write, file_share_read, null,create_always, null

31、, null );if( hf = invalid_handle_value )return 0;/ 寫文件頭bitmapfileheader bfh;memset( &bfh, 0, sizeof( bfh ) );bfh.bftype = mb;bfh.bfsize = sizeof( bfh ) + lbuffersize + sizeof( bitmapinfohead)e; rbfh.bfoffbits = sizeof( bitmapinfoheader ) +sizeof( bitmapfileheader );dword dwwritten = 0;writefile(

32、 hf, &bfh, sizeof( bfh ), &dwwritten, null );/ 寫位圖格式bitmapinfoheader bih;memset( &bih, 0, sizeof( bih ) );bih.bisize = sizeof( bih );bih.biwidth = lwidth;bih.biheight = lheight;bih.biplanes = 1;bih.bibitcount = 24;writefile( hf, &bih, sizeof( bih ), &dwwritten, null );/ 寫位圖數(shù)據(jù)writ

33、efile( hf, pbuffer, lbuffersize, &dwwritten, null );closehandle( hf );return 0;csamplegrabbercb mcb;/ construction/destruction/ccapturevideo:ccapturevideo()/com library intializationif(failed(coinitialize(null) /*, coinit_apartmentthreaded)*/afxmessagebox("coinitialize failed!rn");retu

34、rn;m_hwnd = null;m_pvw = null;m_pmc = null;m_pgb = null;m_pcapture = null;ccapturevideo:ccapturevideo()/ stop media playbackif(m_pmc)m_pmc->stop();if(m_pvw)m_pvw->put_visible(oafalse);m_pvw->put_owner(null);safe_release(m_pcapture);safe_release(m_pmc);safe_release(m_pgb);safe_release(m_pbf)

35、;couninitialize( );int ccapturevideo:enumdevices(hwnd hlist)if (!hlist)return -1;int id = 0;/ 枚舉視頻撲捉設(shè)備icreatedevenum *pcreatedevenum;hresult hr = cocreateinstance(clsid_systemdeviceenum, null,clsctx_inproc_server,iid_icreatedevenum, (void*)&pcreatedevenum);if (hr != noerror)return -1;ccomptr<

36、ienummoniker> pem;hr =pcreatedevenum->createclassenumerator(clsid_videoinputdevicecategory, &pem, 0);if (hr != noerror)return -1;pem->reset();ulong cfetched;imoniker *pm;while(hr = pem->next(1, &pm, &cfetched), hr=s_ok)ipropertybag *pbag;hr = pm->bindtostorage(0, 0, iid_ip

37、ropertybag, (void *)&pbag); if(succeeded(hr)variant var;var.vt = vt_bstr;hr = pbag->read(l"friendlyname", &var, null);if (hr = noerror)tchar str2048;id+;widechartomultibyte(cp_acp,0,var.bstrval, -1, str, 2048, null, null);:sendmessage(hlist, cb_addstring, 0,(lparam)str);sysfrees

38、tring(var.bstrval);pbag->release();pm->release();return id;hresult ccapturevideo:init(int ideviceid, hwnd hwnd)hresult hr;hr = initcapturegraphbuilder();if (failed(hr)afxmessagebox("failed to get video interfaces!"); return hr;/ bind device filter. we know the device because the id w

39、as passed in if(!bindfilter(ideviceid, &m_pbf)return s_false;hr = m_pgb->addfilter(m_pbf, l"capture filter");/ hr = m_pcapture->renderstream(&pin_category_preview, &mediatype_video,/ m_pbf, null, null);/ create a sample grabberhr = m_pgrabber.cocreateinstance( clsid_sampl

40、egrabber );if( !m_pgrabber )afxmessagebox("fail to create samplegrabber, maybeqedit.dll is not registered?");return hr;ccomqiptr< ibasefilter, &iid_ibasefilter > pgrabbase( m_pgrabber );/ 設(shè)置視頻格式am_media_type mt;zeromemory(&mt, sizeof(am_media_type);mt.majortype = mediatype_vi

41、deo;mt.subtype = mediasubtype_rgb24;hr = m_pgrabber->setmediatype(&mt);if( failed( hr ) )afxmessagebox("fail to set media type!");return hr;hr = m_pgb->addfilter( pgrabbase, l"grabber" );if( failed( hr ) )afxmessagebox("fail to put sample grabber in graph");re

42、turn hr;/ try to render preview/capture pinhr = m_pcapture->renderstream(&pin_category_preview, &mediatype_video,m_pbf,pgrabbase,null);if( failed( hr ) )hr = m_pcapture->renderstream(&pin_category_capture, &mediatype_video,m_pbf,pgrabbase,null);if( failed( hr ) )afxmessagebox(&

43、quot;can t build the graph");return hr;hr = m_pgrabber->getconnectedmediatype( &mt );if ( failed( hr) )afxmessagebox("failt to read the connected media type");return hr;videoinfoheader * vih = (videoinfoheader*) mt.pbformat;mcb.lwidth = vih->bmiheader.biwidth;mcb.lheight = v

44、ih->bmiheader.biheight;freemediatype(mt);hr = m_pgrabber->setbuffersamples( false );hr = m_pgrabber->setoneshot( false );hr = m_pgrabber->setcallback( &mcb, 1 );/ 設(shè)置視頻捕捉窗口m_hwnd = hwnd ;setupvideowindow();hr = m_pmc->run();/ 開始視頻捕捉if(failed(hr)afxmessagebox("couldn t run the

45、graph!");return hr; return s_ok;bool ccapturevideo:bindfilter(int deviceid, ibasefilter *pfilter)if (deviceid < 0) return false;/ enumerate all video capture devicesccomptr<icreatedevenum> pcreatedevenum;hresult hr = cocreateinstance(clsid_systemdeviceenum, null,clsctx_inproc_server,ii

46、d_icreatedevenum, (void*)&pcreatedevenum);if (hr != noerror)return false;ccomptr<ienummoniker> pem;hr =pcreatedevenum->createclassenumerator(clsid_videoinputdevicecategory, &pem, 0);if (hr != noerror)return false;pem->reset();ulong cfetched;imoniker *pm;int index = 0;while(hr = p

47、em->next(1, &pm, &cfetched), hr=s_ok, index <= deviceid)ipropertybag *pbag;hr = pm->bindtostorage(0, 0, iid_ipropertybag, (void *)&pbag); if(succeeded(hr)variant var;var.vt = vt_bstr;hr = pbag->read(l"friendlyname", &var, null);if (hr = noerror)if (index = devic

48、eid)pm->bindtoobject(0, 0, iid_ibasefilter, (void*)pfilter);sysfreestring(var.bstrval);pbag->release();pm->release();index+;return true;hresult ccapturevideo:initcapturegraphbuilder()hresult hr;/ 創(chuàng)建 igraphbuilder 接口hr=cocreateinstance(clsid_filtergraph, null, clsctx_inproc_server, iid_igrap

49、hbuilder, (void *)&m_pgb);/ 創(chuàng)建 icapturegraphbuilder2 接口hr = cocreateinstance (clsid_capturegraphbuilder2 , null,clsctx_inproc,iid_icapturegraphbuilder2, (void *) &m_pcapture);if (failed(hr)return hr;m_pcapture->setfiltergraph(m_pgb);hr = m_pgb->queryinterface(iid_imediacontrol, (void *)&m_pmc);if (failed(hr)return hr;hr = m_pgb->queryinterface(iid_ivideowindow, (lpvoid *) &m_pvw);if (failed(hr)return hr;return hr;hresult ccapturevideo:setupvideowindow()hr

溫馨提示

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

評(píng)論

0/150

提交評(píng)論