background
I haven’t written since the outbreak this year. On the one hand, the epidemic has caused me to be restless at home. On the other hand, I have been a little lazy recently. But the work still has to continue, while optimizing the recent project in these days, I sorted out how to use OpenCV and wechat TWO-DIMENSIONAL code engine to achieve two-dimensional code recognition.
Wechat has opened source its QR code decoding function and contributed it to the OpenCV community. Its open source wechat_qrcode project was included in the OpenCV contrib project. It is available from OpenCV 4.5.2.
The project’s github address: github.com/opencv/open…
Address of the model file: github.com/WeChatCV/op…
The scanning engine of wechat has long supported functions such as remote TWO-DIMENSIONAL code detection, automatic focusing and positioning, and multi-code detection and recognition. It is based on THE TWO-DIMENSIONAL code detection of CNN.
Two-dimensional code recognition package
First, define an algoQrcode.h
#pragma once
#include <opencv2/opencv.hpp>
#include <opencv2/wechat_qrcode.hpp>
using namespace cv;
using namespace std;
class AlgoQRCode
{
private:
Ptr<wechat_qrcode::WeChatQRCode> detector;
public:
bool initModel(string modelPath);
string detectQRCode(string strPath);
bool compression(string inputFileName, string outputFileName, int quality);
void release(a);
};
Copy the code
This header defines methods including loading the model, identifying the QR code, releasing resources, and a Detector object for identifying the QR code.
Then write the corresponding source file algoqrcode.cpp
bool AlgoQRCode::initModel(string modelPath) {
string detect_prototxt = modelPath + "detect.prototxt";
string detect_caffe_model = modelPath + "detect.caffemodel";
string sr_prototxt = modelPath + "sr.prototxt";
string sr_caffe_model = modelPath + "sr.caffemodel";
try
{
detector = makePtr<wechat_qrcode::WeChatQRCode>(detect_prototxt, detect_caffe_model, sr_prototxt, sr_caffe_model);
}
catch (const std::exception& e)
{
cout << e.what() << endl;
return false;
}
return true;
}
string AlgoQRCode::detectQRCode(string strPath)
{
if (detector == NULL) {
return "1";
}
vector<Mat> vPoints;
vector<cv::String> vStrDecoded;
Mat imgInput = imread(strPath, IMREAD_GRAYSCALE);
// vStrDecoded = detector->detectAndDecode(imgInput, vPoints);. }bool AlgoQRCode::compression(string inputFileName, string outputFileName, int quality) {
Mat srcImage = imread(inputFileName);
if(srcImage.data ! =NULL)
{
vector<int>compression_params;
compression_params.push_back(IMWRITE_JPEG_QUALITY);
compression_params.push_back(quality); // Image compression parameter. The value ranges from 0 to 100. The higher the value, the higher the image quality
bool bRet = imwrite(outputFileName, srcImage, compression_params);
return bRet;
}
return false;
}
void AlgoQRCode::release(a) {
detector = NULL;
}
Copy the code
Among them:
- The initModel() method, used to load the algorithm model file, must be called first and only once.
- The detectQRCode() method needs to do a lot of pre-processing on the image and then two-dimensional code recognition according to the business scenario. These preprocessing processes are beyond the scope of this article and will be covered in a separate article.
- The compression() method is used to compress the image. Since we use an industrial camera to shoot, the image will be large, about 30M+, so we will compress it before using it.
- The Release () method releases the Detector object at the end of the program.
To recognize the QR code, you simply call the detectAndDecode() method of the Detector object.
Finally, write a main() function to test if it works:
int main(a)
{
AlgoQRCode algoQrCode = AlgoQRCode(a); algoQrCode.initModel("/Users/tony/IdeaProjects/creative-mirror-watcher/mirror/src/main/resources/");
string value = algoQrCode.detectQRCode("/Users/tony/20220216851652_compress.jpeg");
cout<<"value="<<value<<endl;
}
Copy the code
Execution results, identify the content of the TWO-DIMENSIONAL code:
Value ={"osVersion" : "iOS 13.3", "model" : "apple iPhone X"," IP ": "10.184.17.170", "port" : 10123}Copy the code
Write here, basically completed the two-dimensional code recognition package, you can give the upper platform to compile the corresponding algorithm package.
We will eventually need to use Java/Kotlin to call the CV program on the Windows platform. Because the project is a smart device of the host computer program. So you also need to write a JNI program for Java/Kotlin to call, which I won’t elaborate on.
Finally, the CV program and JNI related code is finally compiled into a DLL file for the upper computer program to call, to achieve the final requirements.
conclusion
In fact, the above code can be used on a variety of platforms, whether mobile, desktop, or server. Wechat has opened source a very fast QR code engine, saving us a lot of work.