バックグラウンド
今年の流行以来、私は記事を書いていません。エピデミックにより、自宅での仕事がいらいらするようになりました。また、最近、私は少し怠惰になっています。しかし、作業はまだ継続する必要があります。最近のプロジェクトを最適化するためにこの数日を利用して、OpenCVとWeChatQRコードエンジンを使用してQRコード認識を実現する方法を整理しました。
WeChatはQRコードデコード機能をオープンソース化し、OpenCVコミュニティに貢献しています。そのオープンソースのwechat_qrcodeプロジェクトは、OpenCVcontribプロジェクトに含まれています。OpenCV 4.5.2バージョン以降、直接使用できます。
プロジェクトのgithubアドレス:github.com/opencv/open…
モデルファイルのアドレス:github.com/WeChatCV/op…
WeChatのコードスキャンエンジンは、長距離QRコード検出、自動フォーカスポジショニング、マルチコード検出および認識などの機能を長年にわたってサポートしており、CNNベースのQRコード検出に基づいています。
QRコード識別パッケージ
まず、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();
};
复制代码
ヘッダーファイルは、モデルの読み込み、QRコードの識別、リソースの解放、QRコードの識別のための検出器オブジェクトなどのメソッドを定義します。
次に、対応するソースファイル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); //图像压缩参数,该参数取值范围为0-100,数值越高,图像质量越高
bool bRet = imwrite(outputFileName, srcImage, compression_params);
return bRet;
}
return false;
}
void AlgoQRCode::release() {
detector = NULL;
}
复制代码
の:
- initModel()メソッドは、アルゴリズムモデルファイルをロードするために使用され、最初に呼び出す必要があり、1回だけ呼び出す必要があります。
- detectQRCode()メソッドは、ビジネスシナリオに従って画像に対して多くの前処理を実行してから、QRコードを認識する必要があります。これらの前処理プロセスはこの記事の範囲外であり、将来、別の記事を書く機会があります。
- 画像の圧縮にはcompression()メソッドを使用します。産業用カメラで撮影するため、画像は約30M以上になるため、使用前に圧縮されます。
- release()メソッドは、プログラムの最後に検出器オブジェクトを解放できます。
QRコードの識別は、実際には検出器オブジェクトのdetectAndDecode()メソッドを呼び出しています。
最後に、main()関数を記述して、それが使用可能かどうかをテストします。
int main()
{
AlgoQRCode algoQrCode = AlgoQRCode();
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;
}
复制代码
結果を実行して、QRコードの内容を特定します。
value={
"osVersion" : "iOS 13.3",
"model" : "苹果 iPhone X",
"ip" : "10.184.17.170",
"port" : 10123
}
复制代码
この時点で、QRコード認識のカプセル化は基本的に完了し、対応するアルゴリズムパッケージを上位プラットフォーム用にコンパイルできます。
最終的には、Java/Kotlinを使用してWindowsプラットフォームでcvプログラムを呼び出す必要があります。このプロジェクトはスマートデバイスのホストコンピュータプログラムだからです。したがって、Java / Kotlinが呼び出すjniプログラムを作成する必要があり、このプロセスについては詳しく説明しません。
最後に、cvプログラムとjni関連のコードが最終的にdllファイルにコンパイルされます。このファイルは、最終的な要求を達成するためにホストコンピュータープログラムによって呼び出されます。
要約する
実際、上記のコードは、モバイル、デスクトップ、サーバーなど、さまざまなプラットフォームで使用できます。WeChatは非常に高速なQRコードエンジンをオープンソース化し、多くの作業を節約しました。