画像形態処理とテンプレートマッチングに基づくバーコード桁検出および認識アルゴリズム

目次

1. バーコードデジタル検出

2. バーコードデジタル認識

3. コアプログラムの一部

4、MATLABシミュレーション結果


        画像形態処理とテンプレートマッチングに基づくバーコード番号検出および認識アルゴリズムは、バーコード内の番号を自動的に識別するアルゴリズムです。アルゴリズムは主に、検出と認識の 2 つのステップで構成されます。バーコード検出は、バーコード シンボルがシンボル仕様に準拠しているかどうかを判断できる技術プロセスです。たとえば、特定のアプリケーションでは、バーコード シンボルのパラメータはアプリケーション標準の要件に従う必要があります。コード 128 はその一例であり、そのシステムにコードを適用するために、統一コード委員会と国際記事番号協会は、コードの形式、長さ、およびデータ コンテンツ構造に関してさらなる規制を作成しました。UCC/EAN-128 コードの検出では、それが 128 コードのシンボル仕様に準拠しているかどうかを確認するだけでなく、その長さおよびその他のパラメータも EAN-UCC の要件を満たす必要があります。

1. バーコードデジタル検出

画像の前処理

        画像では、バーコード番号がノイズ、影、不均一な照明などによって妨げられることが多いため、番号検出の前に前処理が必要です。前処理には通常、バーコード数字をより適切に抽出するためのフィルタリング、スムージング、コントラスト強調などが含まれます。

二値化

        バーコード内の数字をより明確に区別するには、画像を 2 値化する必要があります。2 値化では、画像内のピクセル値が黒と白の 2 つのレベルに分割されます。バーコード画像では通常、ストライプとブランクの色が大きく異なるため、2値化することで明確に区別できます。

形態学的処理

        モルフォロジー処理は画像解析で使用される手法で、ノイズの除去や断線の接続などに利用できます。バーコードの桁検出では、通常、形態学的侵食および膨張操作を使用して 2 値化画像を処理します。エロージョンは画像から微細なノイズを除去し、ダイレーションは破線を接続します。

テンプレートマッチング

       テンプレート マッチングは、画像の類似性に基づく検索アルゴリズムであり、ターゲット画像内でテンプレート画像と類似した領域を見つけるために使用されます。バーコード番号検出では、各番号をテンプレート化し、テンプレート マッチングを使用して 2 値化画像内でテンプレートに類似した領域を検出します。見つかった類似領域が、検出したいバーコード番号です。

2. バーコードデジタル認識

特徴抽出

       バーコードの数字を認識する前に、検出された数字から特徴を抽出する必要があります。特徴抽出には、モーメント法、ウェーブレット変換など、さまざまな方法があります。バーコードの数字認識では、通常、幅、長さ、面積などの形状ベースの特徴を使用します。

分類器の設計

        分類器は分類用のアルゴリズムであり、入力の特徴に基づいて分類できます。バーコードの数字認識では、通常、ニューラル ネットワークやサポート ベクター マシンなどの分類器を使用します。これらの分類器は、さまざまな種類の特徴を自動的に学習および認識して、バーコード番号の自動認識を実現します。

分類と識別

       最後に、抽出された特徴を分類器に入力して、分類と認識を行います。分類器は特徴に応じて分類し、認識結果を出力します。出力結果が実際の結果と一致しない場合、認識精度を向上させるために識別器を調整したり、特徴抽出方法を再設計したりする必要があります。

        要約すると、画像形態処理とテンプレート マッチングに基づくバーコード桁検出および認識アルゴリズムは、効果的な自動認識方法です。このアルゴリズムは、前処理、二値化処理、形態素処理、テンプレートマッチングなどのステップによりバーコード数字の検出を実現し、特徴抽出および分類器設計のステップを通じて数字の認識を実現します。このアルゴリズムは高い精度と堅牢性を備えており、バーコード認識の分野で広く使用できます。

3. コアプログラムの一部

..........................................................................
temp = a_hist(max_1);
a_hist(max_1) = 0;
k = 0;
for i=1:n
    if k<a_hist(hist_max(i))
        k = a_hist(hist_max(i));
        max_2 = hist_max(i);
    end
end
a_hist(max_1) = temp;
if max_1>max_2
    k = max_1;
    max_1 = max_2;
    max_2 = k;
end
T = max_1;
k = a_hist(max_1);
for i=max_1:max_2
    if k>a_hist(i)
        k = a_hist(i);
        T = i;
    end
end
[m,n] = size(bar_Gray); %求灰度图的大小
for i=1:m        %对图像进行二值化处理
    for j=1:n
        if bar_Gray(i,j)>T    %选择适当的阈值进行二值化处理
            bar_10(i,j) = 1;
        else
            bar_10(i,j) = 0;
        end
    end
end
%imshow(bar_10);
l = 0;      %检测59根条形码
for i=1:m
    k = 1;
    l = l+1;
    for j=1:n-1
        if bar_10(i,j)~=bar_10(i,j+1)   %比较同一行相邻两点的颜色是否一致
            %bar_x(l,k) = i;
            bar_y(l,k) = j; %记录转折点的纵坐标
            k = k+1;    %准备记录下一个数据点
        end
        if k>61 %点数大于60,该行应该删掉
            l = l-1;
            break
        end
    end
    if k<61 %点数小于60,该行应该删掉
        l = l-1;
    end
end
[m,n] = size(bar_y);
if m<=1 %查看条形码是否有效
    code = '0';
    fprintf(1,'GameOver!\n');
    return
end
for i=1:m            %计算每根条形码的宽度
    for j=1:n-1
        bar_num(i,j) = bar_y(i,j+1) - bar_y(i,j);
        if bar_num(i,j)<0
            bar_num(i,j) = 0;
        end
    end
end
bar_sum = sum(bar_num)/m;   %求每根条形码宽度的平均值
k = 0;
for i=1:59   %计算59根条形码的总宽度
    k = k + bar_sum(i);
end
k = k/95;   %计算单位条形码的宽度
for i=1:59  %计算每根条形码所占位数
    bar_int(i) = round(bar_sum(i)/k);
end
k = 1;
for i=1:59  %将条形码转换成二进制数
    if rem(i,2)
        for j=1:bar_int(i)  %黑色条用1表示
            bar_01(k) = 1;
            k = k+1;
        end
    else
        for j=1:bar_int(i)  %白色条用0表示
            bar_01(k) = 0;
            k = k+1;
        end
    end
end
if ((bar_01(1)&&~bar_01(2)&&bar_01(3))...   %判断起始符是否正确
        &&(~bar_01(46)&&bar_01(47)&&~bar_01(48)&&bar_01(49)&&~bar_01(50))...    %判断中间分隔符是否正确
        &&(bar_01(95)&&~bar_01(94)&&bar_01(93)))    %判断终止符是否正确
    l = 1;
    for i=1:6   %将左侧42位二进制数转换为十进制数
        bar_left(l) = 0;
        for k=1:7
            bar_left(l) = bar_left(l)+bar_01(7*(i-1)+k+3)*(2^(7-k));
        end
        l = l+1;
    end
    l = 1;
    for i=1:6   %将右侧42位二进制数转换为十进制数
        bar_right(l) = 0;
        for k=1:7
            bar_right(l) = bar_right(l)+bar_01(7*(i+6)+k+1)*(2^(7-k));
            k = k-1;
        end
        l = l+1;
    end
end
num_bar = '';
num_first = 0;
................................................................
up2197

4、MATLABシミュレーション結果

おすすめ

転載: blog.csdn.net/ccsss22/article/details/132675216