點擊下方卡片,關注「新機器視覺」公眾號
重磅乾貨,第一時間送達
作者:Tony沈哲
鏈接:https://juejin.cn/post/7079313321446506532
來源:稀土掘金
背景今年自疫情以來,我都沒有寫過文章。一方面是疫情導致居家辦公比較煩躁,另一方面最近有點懶了。但是工作還是要繼續,趁這幾天優化了一下最近的項目,我整理了一下如何使用 OpenCV 和微信二維碼引擎來實現二維碼的識別。
微信開源了其二維碼的解碼功能,並貢獻給 OpenCV 社區。其開源的 wechat_qrcode 項目被收錄到 OpenCV contrib 項目中。從 OpenCV 4.5.2 版本開始,就可以直接使用。該項目 github 地址:
https://github.com/opencv/opencv_contrib/tree/master/modules/wechat_qrcode模型文件的地址:
https://github.com/WeChatCV/opencv_3rdparty微信的掃碼引擎,很早就支持了遠距離二維碼檢測、自動調焦定位、多碼檢測識別等功能,它是基於 CNN 的二維碼檢測。
首先,定義一個 AlgoQrCode.h
#pragmaonce#include<opencv2/opencv.hpp>#include<opencv2/wechat_qrcode.hpp>usingnamespacecv;usingnamespacestd;classAlgoQRCode{private:Ptr<wechat_qrcode::WeChatQRCode>detector;public:boolinitModel(stringmodelPath);stringdetectQRCode(stringstrPath);boolcompression(stringinputFileName,stringoutputFileName,intquality);voidrelease();};該頭文件定義了一些方法,包含了加載模型、識別二維碼、釋放資源等方法,以及一個 detector 對象用於識別二維碼。然後編寫對應的源文件 AlgoQrCode.cpp
boolAlgoQRCode::initModel(stringmodelPath){stringdetect_prototxt=modelPath+"detect.prototxt";stringdetect_caffe_model=modelPath+"detect.caffemodel";stringsr_prototxt=modelPath+"sr.prototxt";stringsr_caffe_model=modelPath+"sr.caffemodel";try{detector=makePtr<wechat_qrcode::WeChatQRCode>(detect_prototxt,detect_caffe_model,sr_prototxt,sr_caffe_model);}catch(conststd::exception&e){cout<<e.what()<<endl;returnfalse;}returntrue;}stringAlgoQRCode::detectQRCode(stringstrPath){if(detector==NULL){return"-1";}vector<Mat>vPoints;vector<cv::String>vStrDecoded;MatimgInput=imread(strPath,IMREAD_GRAYSCALE);//vStrDecoded=detector->detectAndDecode(imgInput,vPoints);....}boolAlgoQRCode::compression(stringinputFileName,stringoutputFileName,intquality){MatsrcImage=imread(inputFileName);if(srcImage.data!=NULL){vector<int>compression_params;compression_params.push_back(IMWRITE_JPEG_QUALITY);compression_params.push_back(quality);//圖像壓縮參數,該參數取值範圍為0-100,數值越高,圖像質量越高boolbRet=imwrite(outputFileName,srcImage,compression_params);returnbRet;}returnfalse;}voidAlgoQRCode::release(){detector=NULL;}其中:initModel() 方法用於加載算法模型文件,必須先調用,並且只需要調用一次即可。模型文件
detectQRCode() 方法需要根據業務場景,先對圖像做很多預處理的工作,然後再進行二維碼的識別。這些預處理的過程,不再本文的討論範圍之列,以後有機會單獨寫一篇文章。
compression() 方法用於壓縮圖像,因為我們使用工業相機拍攝,圖片會很大大概30M+,所以在使用之前會先壓縮一下。
release() 方法可以在程序結束時,釋放 detector 對象。
識別二維碼,其實就是調用 detector 對象的 detectAndDecode() 方法。
最後,寫一個 main() 函數測試一下,是否可用:
執行結果,識別二維碼的內容:
value={"osVersion":"iOS13.3","model":"蘋果iPhoneX","ip":"10.184.17.170","port":10123}寫到這裡,基本上完成了二維碼識別的封裝,可以給上層平台編譯對應的算法包了。我們最終是需要使用 Java/Kotlin 在 Windows 平台上調用該 cv 程序。因為該項目是一款智能設備的上位機程序。所以還需要編寫一個 jni 程序供 Java/Kotlin 調用,這個過程就不再闡述了。最後,將 cv 程序和 jni 相關的代碼最終編譯成一個 dll 文件,供上位機程序調用,實現最終的需求。
總結其實,上述代碼可以供各種平台使用,無論是移動端、桌面端、服務端。微信開源了一款非常快速的二維碼引擎,節省了我們原先大量的工作。
本文僅做學術分享,如有侵權,請聯繫刪文。
