OpenCV 5.0.0
Open Source Computer Vision
読み込み中...
検索中...
見つかりません
🤖 AIによる機械翻訳(非公式) — これは OpenCV 5.0.0 公式リファレンス(英語)を AI (Claude) で自動翻訳したものです。訳に誤りを含む場合があります。正確な情報は 公式英語版(原文) を参照してください。
バーコード認識

前のチュートリアル: Arucoモジュール FAQ

互換性OpenCV >= 4.8

目標

この章では、OpenCVで利用できるバーコードの検出・デコード手法に慣れる。

基礎

バーコードは実生活で商品を識別する主要な技術である。一般的なバーコードは、反射率が大きく異なる黒いバーと白いバーで構成された平行な線のパターンである。バーコード認識とは、バーコードを水平方向にスキャンし、幅や色の異なるバーで構成された2進コードの列、すなわちバーコードのコード情報を取得することである。バーコードの内容は、さまざまなバーコード符号化方式と照合することでデコードできる。現在、EAN-8、EAN-13、UPC-A、UPC-Eの各規格をサポートしている。

https://en.wikipedia.org/wiki/Universal_Product_Code および https://en.wikipedia.org/wiki/International_Article_Number を参照のこと。

関連論文: [313] , [148] , [23]

コード例

メインクラス

バーコード認識のためにいくつかのアルゴリズムが導入された。

コーディングにあたっては、まず cv::barcode::BarcodeDetector オブジェクトを生成する必要がある。このクラスには主に3つのメンバ関数があり、以下で紹介する。

初期化

省略可能で、単一ファイルのONNXネットワーク(sr.onnx)として渡される超解像モデルを使ってバーコード検出器を構築できる。変換済みモデルは https://github.com/WeChatCV/opencv_3rdparty/tree/wechat_qrcode からダウンロードできる。Caffeモデル(sr.prototxt / sr.caffemodel)は現在はサポートされていない。

try
{
app.bardet = makePtr<barcode::BarcodeDetector>(sr_model);
}
catch (const std::exception& e)
{
cout <<
"\n---------------------------------------------------------------\n"
"Failed to initialize super resolution.\n"
"Please, download 'sr.onnx' from\n"
"https://github.com/WeChatCV/opencv_3rdparty/tree/wechat_qrcode\n"
"and put it into the current directory.\n"
"Or you can leave sr_model unspecified.\n"
"---------------------------------------------------------------\n";
cout << e.what() << endl;
return -1;
}

出力を格納する変数を生成する必要がある。

vector<Point> corners;
vector<string> decode_info;
vector<string> decode_type;

検出

cv::barcode::BarcodeDetector::detect メソッドは、方向の一貫性(directional coherence)に基づくアルゴリズムを使用する。まず、各ピクセルの平均二乗勾配を計算する [23] 。次に、画像を正方形のパッチに分割し、各パッチの勾配方向の一貫性(gradient orientation coherence)平均勾配方向(mean gradient direction)を計算する。そして、勾配方向の一貫性が高くかつ勾配方向が類似しているすべてのパッチを連結する。この段階では、マルチスケールのパッチを使って多様なサイズのバーコードの勾配分布を捉え、非最大抑制(non-maximum suppression)を適用して重複した候補をフィルタリングする。最後に、cv::minAreaRect を使ってROIを囲み、矩形のコーナーを出力する。

入力画像内のコードを検出し、検出された矩形の角を出力する:

bardet->detectMulti(frame, corners);

デコード

cv::barcode::BarcodeDetector::decode メソッドは、画像がしきい値より小さい場合にまず(必要に応じて)画像を超解像で拡大し、画像をシャープ化したうえで、OTSUまたは局所二値化によって二値化する。次に、指定したバーコードパターンとの類似度を照合することで、バーコードの内容を読み取る。

検出とデコード

cv::barcode::BarcodeDetector::detectAndDecode は、detectdecode を1回の呼び出しにまとめたものである。この関数の使い方を示す簡単な例を以下に示す:

bardet->detectAndDecodeWithType(frame, decode_info, decode_type, corners);

結果を可視化する:

for (size_t i = 0; i < corners.size(); i += 4)
{
const size_t idx = i / 4;
const bool isDecodable = idx < decode_info.size()
&& idx < decode_type.size()
&& !decode_type[idx].empty();
const Scalar lineColor = isDecodable ? greenColor : redColor;
// draw barcode rectangle
vector<Point> contour(corners.begin() + i, corners.begin() + i + 4);
const vector< vector<Point> > contours {contour};
drawContours(frame, contours, 0, lineColor, 1);
// draw vertices
for (size_t j = 0; j < 4; j++)
circle(frame, contour[j], 2, randColor(), -1);
// write decoded text
if (isDecodable)
{
ostringstream buf;
buf << "[" << decode_type[idx] << "] " << decode_info[idx];
putText(frame, buf.str(), contour[1], FONT_HERSHEY_COMPLEX, 0.8, yellowColor, 1);
}
}

結果

元画像:

image

検出後:

image