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

前のチュートリアル: カスケード分類器の学習
次のチュートリアル: サポートベクターマシン入門

互換性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 を参照のこと。

関連論文: [309] , [149] , [23]

コード例

主要クラス

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

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

初期化

必要に応じて、超解像モデルを指定してバーコード検出器を構築できる。モデルは https://github.com/WeChatCV/opencv_3rdparty/tree/wechat_qrcodesr.caffemodel, sr.prototxt)からダウンロードする必要がある。

try
{
app.bardet = makePtr<barcode::BarcodeDetector>(sr_prototxt, sr_model);
}
catch (const std::exception& e)
{
cout <<
"\n---------------------------------------------------------------\n"
"Failed to initialize super resolution.\n"
"Please, download 'sr.*' from\n"
"https://github.com/WeChatCV/opencv_3rdparty/tree/wechat_qrcode\n"
"and put them into the current directory.\n"
"Or you can leave sr_prototxt and 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 メソッドは、方向のコヒーレンスに基づくアルゴリズムを用いる。まず、各ピクセルの平均二乗勾配を計算する [23] 。次に、画像を正方形のパッチに分割し、各パッチの勾配方向のコヒーレンス平均勾配方向を計算する。続いて、勾配方向のコヒーレンスが高くかつ勾配方向が類似するすべてのパッチを連結する。この段階では、マルチスケールのパッチを用いてさまざまなサイズのバーコードの勾配分布を捉え、非最大抑制を適用して重複した候補を除去する。最後に、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