目標是實現類似掃一掃的功能
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 int i_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,而不是在等待時間中執行代碼
列幾個圖片中截取條形碼的的博客
我是卡在尋找圖像輪廓那一步了,得不到正確返回
opencv 學習(四十)之尋找圖像輪廓findContours()
