背景
今年自疫情以來,我都沒有寫過文章。一方面是疫情導(dǎo)致居家辦公比較煩躁,另一方面最近有點(diǎn)懶了。但是工作還是要繼續(xù),趁這幾天優(yōu)化了一下最近的項(xiàng)目,我整理了一下如何使用 OpenCV 和微信二維碼引擎來實(shí)現(xiàn)二維碼的識(shí)別。
微信開源了其二維碼的解碼功能,并貢獻(xiàn)給 OpenCV 社區(qū)。其開源的 wechat_qrcode 項(xiàng)目被收錄到 OpenCV contrib 項(xiàng)目中。從 OpenCV 4.5.2 版本開始,就可以直接使用。
該項(xiàng)目 github 地址:
https://github.com/opencv/opencv_contrib/tree/master/modules/wechat_qrcode
模型文件的地址:
https://github.com/WeChatCV/opencv_3rdparty
微信的掃碼引擎,很早就支持了遠(yuǎn)距離二維碼檢測(cè)、自動(dòng)調(diào)焦定位、多碼檢測(cè)識(shí)別等功能,它是基于 CNN 的二維碼檢測(cè)。
基于CNN的二維碼檢測(cè)器
二維碼識(shí)別的封裝
首先,定義一個(gè) AlgoQrCode.h
#pragmaonce
#include
#include
usingnamespacecv;
usingnamespacestd;
classAlgoQRCode
{
private:
Ptrdetector;
public:
boolinitModel(stringmodelPath);
stringdetectQRCode(stringstrPath);
boolcompression(stringinputFileName,stringoutputFileName,intquality);
voidrelease();
};
該頭文件定義了一些方法,包含了加載模型、識(shí)別二維碼、釋放資源等方法,以及一個(gè) detector 對(duì)象用于識(shí)別二維碼。
然后編寫對(duì)應(yīng)的源文件 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(detect_prototxt,detect_caffe_model,sr_prototxt,sr_caffe_model);
}
catch(conststd::exception&e)
{
cout<endl;
returnfalse;
}
returntrue;
}
stringAlgoQRCode::detectQRCode(stringstrPath)
{
if(detector==NULL){
return"-1";
}
vectorvPoints;
vectorvStrDecoded;
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);//圖像壓縮參數(shù),該參數(shù)取值范圍為0-100,數(shù)值越高,圖像質(zhì)量越高
boolbRet=imwrite(outputFileName,srcImage,compression_params);
returnbRet;
}
returnfalse;
}
voidAlgoQRCode::release(){
detector=NULL;
}
其中:initModel() 方法用于加載算法模型文件,必須先調(diào)用,并且只需要調(diào)用一次即可。模型文件
detectQRCode() 方法需要根據(jù)業(yè)務(wù)場(chǎng)景,先對(duì)圖像做很多預(yù)處理的工作,然后再進(jìn)行二維碼的識(shí)別。這些預(yù)處理的過程,不再本文的討論范圍之列,以后有機(jī)會(huì)單獨(dú)寫一篇文章。
compression() 方法用于壓縮圖像,因?yàn)槲覀兪褂?a target="_blank">工業(yè)相機(jī)拍攝,圖片會(huì)很大大概30M+,所以在使用之前會(huì)先壓縮一下。
release() 方法可以在程序結(jié)束時(shí),釋放 detector 對(duì)象。
識(shí)別二維碼,其實(shí)就是調(diào)用 detector 對(duì)象的 detectAndDecode() 方法。
最后,寫一個(gè) main() 函數(shù)測(cè)試一下,是否可用:
intmain()
{
AlgoQRCodealgoQrCode=AlgoQRCode();
algoQrCode.initModel("/Users/tony/IdeaProjects/creative-mirror-watcher/mirror/src/main/resources/");
stringvalue=algoQrCode.detectQRCode("/Users/tony/20220216851652_compress.jpeg");
cout<<"value="<endl;
}
執(zhí)行結(jié)果,識(shí)別二維碼的內(nèi)容:
value={
"osVersion":"iOS13.3",
"model":"蘋果iPhoneX",
"ip":"10.184.17.170",
"port":10123
}
寫到這里,基本上完成了二維碼識(shí)別的封裝,可以給上層平臺(tái)編譯對(duì)應(yīng)的算法包了。
我們最終是需要使用 Java/Kotlin 在 Windows 平臺(tái)上調(diào)用該 cv 程序。因?yàn)樵擁?xiàng)目是一款智能設(shè)備的上位機(jī)程序。所以還需要編寫一個(gè) jni 程序供 Java/Kotlin 調(diào)用,這個(gè)過程就不再闡述了。最后,將 cv 程序和 jni 相關(guān)的代碼最終編譯成一個(gè) dll 文件,供上位機(jī)程序調(diào)用,實(shí)現(xiàn)最終的需求。
總結(jié)
其實(shí),上述代碼可以供各種平臺(tái)使用,無論是移動(dòng)端、桌面端、服務(wù)端。微信開源了一款非??焖俚亩S碼引擎,節(jié)省了我們?cè)却罅康墓ぷ鳌?/p>
審核編輯 :李倩
-
二維碼
+關(guān)注
關(guān)注
7文章
406瀏覽量
26371 -
開源
+關(guān)注
關(guān)注
3文章
3218瀏覽量
42329 -
OpenCV
+關(guān)注
關(guān)注
29文章
625瀏覽量
41215
原文標(biāo)題:使用 OpenCV + 微信二維碼引擎實(shí)現(xiàn)二維碼識(shí)別
文章出處:【微信號(hào):vision263com,微信公眾號(hào):新機(jī)器視覺】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
評(píng)論