• 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条形码检测与识别

    基于opencv的条形码区域检测(一)

    opencv 10个步骤检出图片中的条形码

    我是卡在寻找图像轮廓那一步了,得不到正确返回

    opencv 学习(四十)之寻找图像轮廓findContours()

  • 相关阅读:
    Java虚拟机(JVM)中的内存设置详解
    设置TOMCAT的JVM虚拟机内存大小
    什么是SQL注入式攻击
    常见的数据库基础面试题大全
    Struts1与Struts2的12点区别
    sql server导出insert语句
    jsp 将html字符串输出html标签
    GC 基础
    jstl fn标签
    Struts2 中result type属性说明
  • 原文地址:https://www.cnblogs.com/ckrgd/p/14117145.html
Copyright © 2020-2023  润新知