MFC VC++ 使用openCV + zbar 实现摄像头扫码二维码并动态识别
目标是实现类似扫一扫的功能
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()