dbnetを使用してバーコードとテキストをセグメント化します(コード+モデル)+知識の蒸留+テンソルト推論+バーコード分析にpyzbarとzxingを使用します

1.DBnet

1.コードリンク

バーコードとテキストコードを分割:githubリンク:https//github.com/zonghaofan/dbnet_torch(モデルを提供)

2.紙の読書

モデル:

                                            モデル図

微分可能な二値化

一般的なセグメンテーションモデルは、最終的な出力結果を2値化するために固定のしきい値を取ります。この記事の革新は、上の図の(a)に示すように、2値化されたしきい値を学習することです。

微分可能なモジュールを追加することにより、背景と接着されたテキストをよりよく区別するようにしきい値をトレーニングできます。

P:確率マップ

T:しきい値マップ

B ^:おおよそのバイナリマップ

損失関数:
 

損失には3つの主要な部分があります。Lsは縮小後のテキストインスタンスの損失、Lbは2値化後の縮小テキストインスタンスの損失、Ltは2値化しきい値マップの損失、LsとLbの両方がOHEMでbcelossを使用します。 LtはL1lossを使用します。

この論文に記載されている速度には、順伝播と後処理のみが含まれているため、実際には前処理が含まれており、速度はそれほど速くないことに注意してください。

いくつかの結果は

   

2.知識の蒸留

ここで、Tは温度であり、softmax層の出力値がソフトターゲットとして直接使用されます。softmax出力の確率分布エントロピーが比較的小さい場合、負のラベルの値は0に非常に近く、寄与は0に非常に近くなります。損失関数は非常に小さいため、無視できます。したがって、変数「温度」が役立ちます。Tが大きい場合、softmaxの出力確率を和らげることができます。分布が滑らかであるほど、分布のエントロピーが大きくなり、ネガティブラベルによって運ばれる情報が比較的大きくなり、モデルトレーニングはネガティブラベル。つまり、部分的な情報量を持つネガティブラベルから学習することです->ネガティブラベルのノイズの影響を防ぐために温度を高くする必要があります->温度を低くする必要があります。

アイデア:resnet50(教師)を使用して最初にトレーニングし、トレーニング済みのresnet50(教師)を使用してresnet18(学生)の小さなモデルを共同でトレーニングします。実験によると、f1scoreはresnet18のみのトレーニングよりも1ポイント高くなっています。

githubのコードを参照してください。

python train_word_industry_res50.pyは、教師モデルをトレーニングします。

python train_word_industry_res18_kd.pyは、学生モデルをトレーニングします。

3.トーチモデル-> onnx-> tensorrt

アイデア:torch.onnxを使用して.pthを.onnx形式に変換し、推論にtensorrtを使用します。コードについては、githubのmodel_to_onnx.pyを参照してください。

4.バーコードc ++バージョンとpythonバージョンを分析します

1.c ++バージョンのzxingこのリンクを参照してください

Pythonの呼び出しフォームは次のとおりです。

#coding:utf-8
"""用c++编译的zxing进行解析条形码"""
import subprocess
import os
import time
import sysos.path.join(os.path.dirname(__file__)))


def zxing_parse_code(imgpath):
    zxing_bin_path = os.path.join(os.path.dirname(__file__), "zxing")
    assert os.path.exists(zxing_bin_path), "zxing bin file not exist!"

    command = '{} --test-mode {}'.format(zxing_bin_path, imgpath)
    process = subprocess.Popen(command, shell=True, stdout=subprocess.PIPE)
    process.wait()
    output = process.communicate()[0].decode("utf-8").replace(' ', '').split('\n')
    # print(output)
    try:
        if 'Detected:' in output[1]:
            return output[1][9:]
        else:
            return None
    except:
        return None

2.インストール環境:

ubuntu:
apt-get install zbar-tools

apt-get install python-jpype

centos:

yum install zbar-devel

pip install pyzbar

pip install zxing

3.コードケース 

#coding:utf-8
import pyzbar.pyzbar as pyzbar
import time
import shutil
import zxing
import cv2

def parse_code(codeimg, reader):
    """
    输入矫正过的条形码图片输出解析结果
    :param codeimg: 矫正过的条形码图片
    :return: 条形码解析结果
    """
    gray = cv2.cvtColor(codeimg, cv2.COLOR_BGR2GRAY)
    gray_h, gray_w = gray.shape
    barcodes1 = pyzbar.decode(gray)
    # barcodes2 = pyzbar.decode(np.rot90(np.rot90(gray)))
    # print('==barcodes2:', barcodes2)
    def parse_results(barcode):
        # for barcode in barcodes:
        # 提取条形码的位置
        # (x, y, w, h) = barcode.rect
        # 字符串转换
        barcodeData = barcode.data.decode("utf-8")
        return barcodeData

    if len(barcodes1):
        barcodeData = parse_results(barcodes1[0])
        if len(barcodeData) >= 10:#条形码位数大于10位
            return barcodeData
    else:


        if gray_h>gray_w:
            cv2.imwrite('./out_clip.jpg', np.rot90(codeimg)[...,::-1])
        else:
            cv2.imwrite('./out_clip.jpg', codeimg[...,::-1])
        barcode = reader.decode('./out_clip.jpg')
        # print('==barcode:', barcode)
        try:
            return barcode.raw
        except:
            return None

def debug_parse_code():
    reader = zxing.BarCodeReader()
    path = './5.png'
    img = cv2.imread(path)
    code_res = parse_code(img, reader)
    print('==code_res:', code_res)

if __name__ == '__main__':
    debug_parse_code()

おすすめ

転載: blog.csdn.net/fanzonghao/article/details/107199538