MFC VC++ 使用openCV + zbar 實現攝像頭掃碼二維碼並動態識別
阿新 • • 發佈:2020-12-10
目標是實現類似掃一掃的功能
1.使用OpenCV獲取攝像頭的影象
2.再用opencv處理圖片,把一張圖片中的二維碼(或條形碼)部分剪下下來(這個沒實現)
3.用zbar識別剪下後的圖片
這裡只實現了while接收攝像頭圖片建立執行緒去識別,即每接收一個圖片就建立執行緒幹活,
幹完沒識別就自己結束,識別了就結束while,或超時了結束while
這裡會有一個建立多個執行緒的問題,但我把 strQRData 獨佔,測試沒有發現問題
這裡在筆記本上測試可以實現掃一掃的功能,但在效能差一點的windows平板電腦上太卡了,沒有實際使用的價值
把程式碼放上來吧
1 BOOL xxxDlg::OnInitDialog()
//這是放到init中的一段程式碼,目的是開啟對話方塊就開始掃碼
//這裡是實現把opencv的圖片顯示放到pic控制元件中 2 namedWindow("view", WINDOW_AUTOSIZE); 3 HWND hWnd = (HWND)cvGetWindowHandle("view"); 4 HWND hParent = ::GetParent(hWnd); 5 ::SetParent(hWnd, GetDlgItem(IDC_STA_Scanning)->m_hWnd); 6 GetDlgItem(IDC_STA_Scanning)->ShowWindow(SW_SHOW); 7 ::ShowWindow(hParent, SW_HIDE);8 9 VideoCapture capture(0); 10 if (!capture.isOpened()) 11 { 12 MessageBox(_T("fail to open")); 13 EndDialog(IDCANCEL);//退出視窗 14 return FALSE; 15 } 16 Mat frame; 17 Mat imageGray; 18 hSemaphore = CreateSemaphore(NULL, 2, 2, NULL);// 建立訊號量物件 19 inti_timeCount = 0;//20秒 20 while (b_scanning && (strQrData.IsEmpty()) && (i_timeCount < 20000)) 21 { 22 capture >> frame; 23 if (frame.data) 24 { 25 cvtColor(frame, imageGray, CV_RGB2GRAY); 26 AfxBeginThread(ThreadScanning, &imageGray, 0, 0, 0); 27 imshow("view", frame); 28 i_timeCount += 60;//這個時間控制差距比較大,需要根據實際機器的測試來確定20秒 29 waitKey(30); 30 } 31 else 32 { 33 b_scanning = FALSE; 34 } 35 } 36 if (strQrData.IsEmpty()) 37 { 38 MessageBox(_T("識別失敗,請重新識別或手動輸入")); 39 } 40 else 41 { 42 MessageBox(strQrData); 43 } 44 strQrData.Empty(); 45 b_scanning = TRUE; 46 EndDialog(IDCANCEL);//退出視窗 47 return TRUE; // return TRUE unless you set the focus to a control 48 //執行緒函式 49 50 BOOL b_scanning = TRUE; 51 CString strQrData; 52 HANDLE hSemaphore;//訊號量物件控制代碼 53 54 55 UINT ThreadScanning(LPVOID pParam) 56 { //執行緒要呼叫的函式 57 Mat *frame = (Mat *)pParam; 58 string ret; 59 ret = QRCode::GetQR(*frame); 60 if (!ret.empty()) 61 { 62 WaitForSingleObject(hSemaphore, INFINITE);// 試圖進入訊號量關口 63 b_scanning = FALSE; 64 strQrData = ret.c_str(); 65 ReleaseSemaphore(hSemaphore, 1, NULL);// 釋放訊號量計數 66 } 67 return 0; 68 }
這裡還要優化的地方
1. 識別圖片中二維碼和條形碼的區域,擷取後再識別二維碼的資料,這樣處理圖片會更快
2. 在while的迴圈中,設執行程式碼時間是codeTime,等待的時間是waitTime
現在程式碼的執行一輪迴圈的時間是codeTime + waitTime,而不是在等待時間中執行程式碼