VideoCapture.cpp
上传用户:czshopping
上传日期:2022-05-22
资源大小:5430k
文件大小:14k
源码类别:

视频捕捉/采集

开发平台:

Visual C++

  1. // VideoCapture.cpp: implementation of the CVideoCapture class.
  2. //
  3. //////////////////////////////////////////////////////////////////////
  4. #include "stdafx.h"
  5. #include "VideoCapture.h"
  6. #include "resource.h"
  7. #include "detect.h"
  8. #ifdef _DEBUG
  9. #undef THIS_FILE
  10. static char THIS_FILE[]=__FILE__;
  11. #define new DEBUG_NEW
  12. #endif
  13. //#include "FaceImageCtrl.h"
  14. //#include "FaceImageCtrl_i.c"
  15. //////////////////////////////////////////////////////////////////////
  16. // Construction/Destruction
  17. //////////////////////////////////////////////////////////////////////
  18. CVideoCapture::CVideoCapture()
  19. {
  20. m_hParentWnd=NULL;
  21. m_iMaxCapFrame=1;
  22. m_pBuffer=NULL;
  23. m_iConnectedDriverID=-1;
  24. m_hCapWnd=NULL;
  25. m_iHeight=240;
  26. m_iWidth=320; 
  27. m_bHasOverlay=FALSE;
  28. m_bInit=FALSE;   
  29. m_bCapture=FALSE;  //正在扑捉
  30. m_PreViewRate=30; //预揽帧数
  31. m_bStorageData=FALSE;//要求保存扑捉
  32. lpVideo=this;
  33. m_dwBufferSize=0;
  34. nOverlayColor = 0;
  35. nOverlayShape = 0;
  36. }
  37. CVideoCapture::~CVideoCapture()
  38. {
  39. }
  40. BOOL CVideoCapture::EnableVideo(long nDriver)
  41. {
  42. if(!ConnectDev(nDriver))return FALSE;
  43. return TRUE;
  44. }
  45. BOOL CVideoCapture::EnableAnyVideo()
  46. {
  47. if (m_MemDC.GetSafeHdc()==NULL)
  48. {
  49. m_MemDC.CreateCompatibleDC(m_pDC);
  50. }
  51. if(!ConnectDev(-1))
  52. return FALSE;
  53. return TRUE;
  54. }
  55. void CVideoCapture::DisableVideo()
  56. {
  57. DisConnectDev();
  58. }
  59. //构建扑捉窗
  60. BOOL CVideoCapture::CaptureInit(HWND hwndParent) 
  61. {
  62. int nCapWndID=0;
  63. if (hwndParent==NULL) return FALSE;
  64. if (!InitVideoBuffer())
  65. return FALSE;
  66. m_hParentWnd=hwndParent;
  67. m_hCapWnd= capCreateCaptureWindow(
  68. (LPSTR)"Face Video Capture Window", WS_CHILD|WS_VISIBLE,
  69. 0, 0,m_iWidth,m_iHeight,
  70.  hwndParent, nCapWndID );
  71. if (hwndParent == NULL)
  72. {
  73. m_hParentWnd=NULL;
  74. return FALSE;
  75. }
  76. m_pDC=CWnd::FromHandle(m_hParentWnd)->GetDC();
  77. if (m_MemDC.GetSafeHdc()==NULL)
  78. {
  79. m_MemDC.CreateCompatibleDC(m_pDC);
  80. }
  81. m_Bitmap.CreateCompatibleBitmap(m_pDC,m_iWidth,m_iHeight);
  82. m_pRotateBuffer=new BYTE[m_iHeight*m_iWidth*4];
  83. m_MoveTrace.Initialize(m_iWidth, m_iHeight,3,3);
  84. return TRUE;
  85. }
  86. void CVideoCapture::CaptureEnd()
  87. {
  88. CWnd::FromHandle(m_hParentWnd)->ReleaseDC(m_pDC);
  89. m_Bitmap.DeleteObject();
  90. if (m_MemDC.GetSafeHdc()!=NULL)
  91. {
  92. m_MemDC.DeleteDC();
  93. }
  94. delete m_pRotateBuffer;
  95. m_MoveTrace.Uninitialize();
  96. DisConnectDev();
  97. //::DestroyWindow(m_hCapWnd); 
  98. if (m_pBuffer)
  99. delete (m_pBuffer); 
  100. m_pBuffer=NULL;
  101. m_hParentWnd=NULL;
  102. m_iMaxCapFrame=1;
  103. m_pBuffer=NULL;
  104. m_hCapWnd=NULL;
  105. m_iHeight=0;
  106. m_iWidth=0; 
  107. m_bHasOverlay=FALSE;
  108. m_bInit=FALSE;   
  109. m_bCapture=FALSE;  //正在扑捉
  110. m_bStorageData=FALSE;//要求保存扑捉
  111. }
  112. //获取当前设置的设备号
  113. long CVideoCapture::GetCurrentDriver()
  114. {
  115. return m_iConnectedDriverID;
  116. }
  117. //取指定设备号对应名称
  118. BSTR CVideoCapture::GetDriverName(long nDriver)
  119. {
  120. char szDeviceName[160];
  121. if (!capGetDriverDescription(nDriver,szDeviceName,
  122. sizeof(szDeviceName), NULL,0) )
  123. szDeviceName[0]=0;
  124. m_bstr = szDeviceName;
  125. return m_bstr;
  126. }
  127. //返回可用设备数
  128. long CVideoCapture::GetVideoDriverCount()
  129. {
  130. int wDriverIndex;
  131. char szDeviceName[160];
  132. for (wDriverIndex=0; wDriverIndex < 10; wDriverIndex++)
  133. {
  134. szDeviceName[0]=0;
  135. if (capGetDriverDescription(wDriverIndex,szDeviceName,
  136. sizeof(szDeviceName), NULL,0) )
  137. {
  138. if (szDeviceName[0]==0)
  139. break;
  140. }
  141. else
  142. break;
  143. }
  144. return wDriverIndex;
  145. }
  146. //连接扑捉设备
  147. BOOL CVideoCapture::ConnectDev(long DriverID)
  148. {
  149. CAPDRIVERCAPS CapDrvCaps;
  150. if (m_hCapWnd==NULL)
  151. return FALSE;
  152. if (m_iConnectedDriverID!=DriverID)
  153. {
  154. DisConnectDev();
  155. }
  156. m_iConnectedDriverID=-1;
  157. //auto scan valid driver
  158. if(-1 == DriverID)
  159. {
  160. for (int i=0;i<GetVideoDriverCount();i++)
  161. {
  162. if(capDriverConnect(m_hCapWnd, i))
  163. if (capDriverGetCaps(m_hCapWnd, &CapDrvCaps, sizeof(CAPDRIVERCAPS)) )
  164. if (CapDrvCaps.fCaptureInitialized)
  165. break;
  166. }
  167. if (i>=GetVideoDriverCount())
  168. {
  169. return FALSE;
  170. }
  171. else
  172. m_iConnectedDriverID=i;
  173. }
  174. else
  175. {
  176. if(!capDriverConnect(m_hCapWnd, DriverID))
  177. {
  178. return FALSE;
  179. }
  180. if (!capDriverGetCaps(m_hCapWnd, &CapDrvCaps, sizeof(CAPDRIVERCAPS)) )
  181. return FALSE;
  182. else
  183. {
  184. if (!CapDrvCaps.fCaptureInitialized)
  185. {
  186. return FALSE;
  187. }
  188. else
  189. m_iConnectedDriverID=DriverID;
  190. }
  191. }
  192. if (!SetVideoFormat())
  193. {
  194. DisConnectDev();
  195. return FALSE;
  196. }
  197. //set call back function
  198. if (!InitVideoBuffer())
  199. {
  200. DisConnectDev();
  201. return FALSE;
  202. }
  203. if (!capSetCallbackOnFrame(m_hCapWnd,FrameCallbackProc))
  204. {
  205. DisConnectDev();
  206. return FALSE;
  207. }
  208. m_bHasOverlay=CapDrvCaps.fHasOverlay; 
  209. m_bInit = TRUE;
  210. MoveWindow(320,0,320,240);
  211. SetPreviewRate();
  212. return TRUE;
  213. }
  214. BOOL CVideoCapture::SetVideoFormat(int Width,int Height)
  215. {
  216. ///////////////Set Video format(frame width and height)/////////////
  217. DWORD dwSize;
  218. LPBITMAPINFO  lpbi;  //位图信息描述
  219. dwSize = capGetVideoFormatSize(m_hCapWnd);
  220. lpbi   = (LPBITMAPINFO)malloc(dwSize);
  221. if (lpbi==NULL)
  222. return FALSE;
  223. capGetVideoFormat(m_hCapWnd,lpbi,dwSize);
  224. lpbi->bmiHeader.biBitCount = 24;
  225. lpbi->bmiHeader.biWidth = Width;
  226. lpbi->bmiHeader.biHeight = Height;
  227. lpbi->bmiHeader.biCompression = BI_RGB;
  228. lpbi->bmiHeader.biSizeImage =0;
  229. if(!capSetVideoFormat( m_hCapWnd, lpbi, dwSize))
  230. {
  231. //return FALSE;
  232. }
  233. capGetVideoFormat(m_hCapWnd,lpbi,dwSize);
  234. m_iWidth=lpbi->bmiHeader.biWidth;
  235. m_iHeight=lpbi->bmiHeader.biHeight;
  236. if ((lpbi->bmiHeader.biBitCount>24)||(lpbi->bmiHeader.biBitCount==12))
  237. {
  238. //Commented by Yuan 2002/10/21
  239. //free(lpbi);
  240. //return FALSE;
  241. }
  242. m_dwBufferSize=lpbi->bmiHeader.biSizeImage ;
  243. m_bitCount=lpbi->bmiHeader.biBitCount;
  244. free(lpbi);
  245. return TRUE;
  246. }
  247. void CVideoCapture::DisConnectDev()
  248. {
  249. if (m_hCapWnd==NULL)
  250. return ;
  251. //if (m_bCapture)   
  252. // capCaptureStop(m_hCapWnd);
  253. capSetCallbackOnFrame(m_hCapWnd,NULL);
  254. capDriverDisconnect(m_hCapWnd);
  255. }
  256. BOOL CVideoCapture::Preview(BOOL onoff)
  257. {
  258. if(!m_bInit)
  259. {
  260. return FALSE;
  261. }
  262. capPreview(m_hCapWnd,onoff);
  263. return TRUE;
  264. }
  265. BOOL CVideoCapture::SetPreviewRate(int rate)
  266. {
  267. if((!m_bInit)||(rate<0))
  268. {
  269. return FALSE;
  270. }
  271. if(rate == 0) rate = 5;
  272. if (!capPreviewRate(m_hCapWnd,(WORD) ((1000.0 / rate) + 0.5)) )
  273. return FALSE;
  274. m_PreViewRate=rate;
  275. capPreview(m_hCapWnd,true);
  276. return TRUE;
  277. }
  278. BOOL CVideoCapture::SetScrollPos(LPPOINT pos)
  279. {
  280. if(!m_bInit)return FALSE;
  281. return capSetScrollPos(m_hCapWnd,pos);
  282. }
  283. BOOL CVideoCapture::StretchVideo(BOOL bStretch)
  284. {
  285. if(!m_bInit)return FALSE;
  286. //return capPreviewScale(m_hParentWnd,bStretch);
  287. return capPreviewScale(m_hCapWnd,bStretch);
  288. }
  289. BOOL CVideoCapture::SetOverlay(bool bOverlay)
  290. {
  291. if(!m_bInit)return FALSE;
  292. if (!m_bHasOverlay)return FALSE;
  293. return capOverlay(m_hCapWnd,bOverlay);
  294. }
  295. void CVideoCapture::SetOverlayColor(int nColor)
  296. {
  297. nOverlayColor = nColor;
  298. }
  299. void CVideoCapture::SetOverlayShape(int nShape)
  300. {
  301. nOverlayShape = nShape;
  302. }
  303. void CVideoCapture::OverlayDraw(RECT rect)
  304. {
  305. HDC dc;
  306. HPEN  penColor;
  307. HPEN  penOld;
  308. HBRUSH  brush;
  309. HBRUSH  brushOld;
  310. LOGBRUSH  log;
  311. if (m_hCapWnd!=NULL)
  312. {
  313. dc=::GetDC(m_hCapWnd);
  314. log.lbStyle =BS_NULL;
  315. log.lbColor =0;
  316. log.lbHatch =0;
  317. brush=CreateBrushIndirect(&log);
  318. switch(nOverlayColor)
  319. {
  320. case 0:
  321. penColor = ::CreatePen(PS_SOLID,2,RGB(255,0,0));
  322. break;
  323. case 1:
  324. penColor = ::CreatePen(PS_SOLID,2,RGB(0,255,0));
  325. break;
  326. case 2:
  327. penColor = ::CreatePen(PS_SOLID,2,RGB(0,0,255));
  328. break;
  329. default:
  330. break;
  331. }
  332. penOld=(HPEN)::SelectObject(dc,penColor);
  333. brushOld=(HBRUSH)::SelectObject(dc,brush);
  334. ::SetBkMode(dc,TRANSPARENT);
  335. switch(nOverlayShape)
  336. {
  337. case 0:
  338. ::Ellipse(dc,rect.left ,rect.top ,rect.right ,rect.bottom );
  339. break;
  340. case 1:
  341. ::Ellipse(dc,rect.left ,rect.top ,rect.right ,rect.top + rect.right-rect.left);
  342. break;
  343. case 2:
  344. ::Rectangle(dc,rect.left,rect.top,rect.right,rect.bottom);
  345. break;
  346. default:
  347. break;
  348. }
  349. if (penOld!=NULL)
  350. ::SelectObject(dc,penOld);
  351. if (brushOld!=NULL)
  352. ::SelectObject(dc,brushOld);
  353. ::DeleteObject(penColor);
  354. ::DeleteObject(brush);
  355. ::ReleaseDC(m_hCapWnd,dc); 
  356. }
  357. }
  358. void CVideoCapture::ShowVideoFormatDialog()
  359. {
  360. if(!m_bInit)return ;
  361. capDlgVideoFormat(m_hCapWnd);
  362. GetVideoFormat();
  363. }
  364. void CVideoCapture::ShowVideoSourceDialog()
  365. {
  366. if(!m_bInit)return ;
  367. capDlgVideoSource(m_hCapWnd);
  368. GetVideoFormat();
  369. }
  370. BOOL CVideoCapture::GrabVideo(unsigned char *pImageData)
  371. {
  372. BOOL Result;
  373. if(!m_bInit)return FALSE;
  374. m_bStorageData=TRUE;
  375. Result=capGrabFrameNoStop(m_hCapWnd);
  376. m_bStorageData=FALSE;
  377. if (Result)
  378. GetImage(pImageData);
  379. return Result;
  380. }
  381. void CVideoCapture::SaveImage(LPVIDEOHDR lpVHdr)
  382. {
  383. memcpy(m_pBuffer, lpVHdr->lpData, m_dwBufferSize);
  384. }
  385. //取帧数据
  386. void CVideoCapture::GetImage(unsigned char *pImageData)
  387. {
  388. memcpy(pImageData,m_pBuffer,  m_dwBufferSize);
  389. }
  390. //初始化帧缓冲
  391. BOOL CVideoCapture::InitVideoBuffer()
  392. {
  393. DWORD Size;
  394. if (m_pBuffer)
  395. delete (m_pBuffer); 
  396. Size=3*m_iWidth*m_iHeight;
  397. m_pBuffer=new unsigned char[Size];
  398. return (m_pBuffer!=NULL);
  399. }
  400. void CVideoCapture::MoveWindow(int x,int y,int nWidth,int nHeight)
  401. {
  402. //m_iWidth = nWidth;
  403. //m_iHeight = nHeight;
  404. ::MoveWindow(m_hCapWnd,x,y,nWidth,nHeight,TRUE); 
  405. }
  406. void CVideoCapture::GetVideoFormat()
  407. {
  408. DWORD dwSize;
  409. LPBITMAPINFO  lpbi;  //位图信息描述
  410. dwSize = capGetVideoFormatSize(m_hCapWnd);
  411. lpbi   = (LPBITMAPINFO)malloc(dwSize);
  412. capGetVideoFormat(m_hCapWnd,lpbi,dwSize);
  413. //Modified by Yuanzujun 2002/10/21
  414. if ( (lpbi->bmiHeader.biWidth != 320) || (lpbi->bmiHeader.biHeight!=240) )
  415. {
  416. AfxMessageBox("图像格式目前版本只支持320*240!请重新设置!");
  417. free(lpbi);
  418. return;
  419. }
  420. if ( lpbi->bmiHeader.biBitCount != 24 )
  421. {
  422. AfxMessageBox("图像深度目前版本只支持'RGB 24'!n请重新设置!");
  423. free(lpbi);
  424. return;
  425. }
  426. if((m_iWidth!=lpbi->bmiHeader.biWidth) || (m_iHeight!=lpbi->bmiHeader.biHeight))
  427. {
  428. m_iWidth=lpbi->bmiHeader.biWidth;
  429. m_iHeight=lpbi->bmiHeader.biHeight;
  430. InitVideoBuffer();
  431. }
  432. m_dwBufferSize=lpbi->bmiHeader.biSizeImage;
  433. m_bitCount=lpbi->bmiHeader.biBitCount;
  434. free(lpbi);
  435. }
  436. int CVideoCapture::GetVideoWidth()
  437. {
  438. return m_iWidth;
  439. }
  440. int CVideoCapture::GetVideoHeight()
  441. {
  442. return m_iHeight;
  443. }
  444. BOOL CVideoCapture::WriteAsBMP(char* szFileName,unsigned char* pImgData,int nWidth,int nHeight)
  445. {
  446. char aFileName[255];
  447. int nStrLen;
  448. if(strstr(szFileName,".")==NULL)
  449. {
  450. strcpy(aFileName,szFileName);
  451. strcat(aFileName,".bmp");
  452. }
  453. else
  454. {
  455. nStrLen=strlen(szFileName)-strlen(strstr(szFileName,"."));
  456. strncpy(aFileName,szFileName,nStrLen);
  457. aFileName[nStrLen]='';
  458. strcat(aFileName,".bmp");
  459. }
  460. BITMAPFILEHEADER bmfHdr; // Header for Bitmap file
  461. /* Fill in file type (first 2 bytes must be "BM" for a bitmap) */
  462. bmfHdr.bfType = 0x4d42;  // "BM"
  463. // Calculate the file size by adding the DIB size to sizeof(BITMAPFILEHEADER)
  464. int nImgWidth;
  465. if (nWidth%4==0)
  466. {
  467. nImgWidth=nWidth*3;
  468. }
  469. else
  470. {
  471. nImgWidth=nWidth*3+nWidth%4;
  472. }
  473. bmfHdr.bfSize =(DWORD)( nImgWidth*nHeight + sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER) );
  474. bmfHdr.bfReserved1 = 0;
  475. bmfHdr.bfReserved2 = 0;
  476. bmfHdr.bfOffBits = (DWORD)(sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER));
  477. BITMAPINFOHEADER BMIH;   // Pointer to DIB info structure
  478. BMIH.biSize=sizeof(BITMAPINFOHEADER);
  479. BMIH.biHeight=nHeight;
  480. BMIH.biWidth=nWidth;
  481. BMIH.biPlanes=1;
  482. BMIH.biBitCount=24;
  483. BMIH.biCompression=BI_RGB;
  484. BMIH.biSizeImage=nImgWidth*nHeight;
  485. BMIH.biXPelsPerMeter=0xec4;
  486. BMIH.biYPelsPerMeter =0xec4;
  487. BMIH.biClrUsed =0;
  488. BMIH.biClrImportant=0;
  489. FILE *pFile;
  490. pFile=fopen(aFileName,"wb");
  491. if (pFile==NULL)
  492. {
  493. return FALSE;
  494. }
  495. BYTE aTemp[12]={0};
  496. try {
  497. // Write the file header
  498. fwrite((BYTE*)&bmfHdr,1,sizeof(BITMAPFILEHEADER),pFile);
  499. // Write the DIB header
  500.         fwrite((BYTE*)&BMIH,1,sizeof(BITMAPINFOHEADER),pFile);
  501. // Write the DIB bits
  502. int i;
  503. for (i=0;i<nHeight;i++)
  504. {
  505. fwrite(pImgData+i*nWidth*3,1,nWidth*3,pFile);
  506. fwrite(aTemp,1,nWidth%4,pFile);
  507. }
  508.     }
  509.     catch(...)
  510. {
  511. fclose(pFile);
  512.         return FALSE;
  513.     }
  514. fclose(pFile);
  515.     return TRUE;
  516. }
  517. LRESULT FAR PASCAL FrameCallbackProc(HWND hWnd,  LPVIDEOHDR lpVHdr)
  518. {
  519. if (lpVideo == NULL) 
  520. return (LRESULT) TRUE;
  521. int x, y, nX, nY;
  522. nX = 1;
  523. nY = 1;
  524. const int nMosaicWidth=4;
  525. const int nMosaicHeight=4;
  526. CBitmap *pOldBitmap;
  527. pOldBitmap=lpVideo->m_MemDC.SelectObject(&lpVideo->m_Bitmap);
  528. lpVideo->m_MoveTrace.GetDIBBit(lpVHdr->lpData);
  529. lpVideo->m_MoveTrace.Extract(nX, nY);
  530. lpVideo->m_MoveTrace.Grey(); //m_Grey1
  531. lpVideo->m_MoveTrace.Sobel(); //m_Grey1
  532. int nThreshold=lpVideo->m_MoveTrace.GetThreshold(30);// ThresholdDIB((LPSTR)lpVideo->m_MoveTrace.m_pGrey1,320,240);
  533. lpVideo->m_MoveTrace.FrameMinus(); //m_pGrey[x]=abs(m_pGrey1[x] - m_pGrey2[x]);
  534. lpVideo->m_MoveTrace.Mosaic(nMosaicWidth, nMosaicHeight); //m_pGrey --> m_pMosaic
  535. lpVideo->m_MoveTrace.Dither(nThreshold); //m_pMosaic
  536. for( y=0;y<lpVideo->m_iHeight;y+=1)
  537. {
  538. for( x=0;x<lpVideo->m_iWidth;x+=1)
  539. {
  540. int nPos = y/nY*lpVideo->m_iWidth/nX+x/nX;
  541. int nTemp = lpVideo->m_MoveTrace.m_pMosaic[nPos];
  542. // int nTemp = lpVideo->m_MoveTrace.m_pGrey[nPos];
  543. // int nTemp = lpVideo->m_MoveTrace.m_pGrey1[nPos];
  544. lpVideo->m_MemDC.SetPixel(x,lpVideo->m_iHeight-1-y,RGB(nTemp,nTemp,nTemp));
  545. }
  546. }
  547. lpVideo->m_MoveTrace.SaveFrame(); //m_pGrey2[x] = m_pGrey1[x];
  548. CRect rect;
  549. bool bRet1=lpVideo->m_MoveTrace.Rectangle(rect,100,5);//m_pMosaic
  550. if (bRet1)
  551. {
  552. lpVideo->m_MemDC.Draw3dRect(&rect, RGB(0, 255, 0), RGB(0, 255, 0));
  553. lpVideo->m_MemDC.Draw3dRect(&lpVideo->m_MoveTrace.m_NextRect, RGB(0, 0, 255), RGB(0, 0, 255));
  554. lpVideo->m_MemDC.Draw3dRect(&lpVideo->m_MoveTrace.m_CurrentRect, RGB(255, 0, 0), RGB(255, 0, 0));
  555. }
  556. // SetDIBitsToDevice(lpVideo->m_pDC->m_hDC,0,0,m_iWidth,m_iHeight,0,0,)
  557. BOOL bRet=lpVideo->m_pDC->BitBlt(
  558. 0,0,
  559. lpVideo->m_iWidth,
  560. lpVideo->m_iHeight,
  561. &lpVideo->m_MemDC,
  562. 0,0,
  563. SRCCOPY);
  564. lpVideo->m_MemDC.SelectObject(pOldBitmap);
  565. //保存图片
  566. if (lpVideo->m_bStorageData)
  567. {
  568. lpVideo->SaveImage(lpVHdr);
  569. CTime Time=CTime::GetCurrentTime();
  570. CString strTime = Time.Format("%H%M%S");
  571. lpVideo->WriteAsBMP(strTime.GetBuffer(strTime.GetLength()),lpVHdr->lpData,320,240);
  572. lpVideo->m_bStorageData = FALSE;
  573. }
  574. return (LRESULT) TRUE;
  575. }