yolov5 は小さなターゲットを検出します (ソース コード付き)

yolov5 小型ターゲット検出 (ソースコードによる画像切り取り方法)

6.30 カット小絵のラベルデータ処理を更新

序文

誰もがyolov5に精通しており、非常に用途が広いですが、いくつかの小さなターゲットを検出する効果は非常に貧弱です.
YOLOv5 アルゴリズムのトレーニング プロセス中、デフォルトの画像サイズは 640x640 ピクセル (img-size) です. 小さなターゲットを検出するには、単純に img-size を 4000*4000 に変更すると、必要なメモリが削減されます.それはほとんど不可能です。
以下は、6k * 4k の写真、8 つの写真、および 1 つの単語に対する小さなターゲット検出トレーニングの結果です: 悪い
ここに画像の説明を挿入
データセット (道路標識):
ここに画像の説明を挿入

画像カット

最も簡単な方法は、この大きな画像を小さな画像に分割することです.いくつかの質問については、オープン ソース フレームワーク SAHI [1]を参照してください:

1. 単純なカットでは、カット後の各画像のサイズが同じであることを確認する必要があります;
2. カット プロセスでは必然的にターゲットが切り取られ、「融合」領域を設定する必要があります;
3. データカット後のセットは小さい絵のデータセットなので、対象を検出する際は小さい絵しか検出できません。次に、検出後に小さな画像をマージする必要があります。(問題)

1.画像切り取り

一般的な構造図:
青と緑は 4*4 = 16 のサブイメージを切り取り、赤と青のフレームの部分は融合イメージで、混合比は 0.2 です。
ここに画像の説明を挿入

これは簡単です。ブログpython を参照して画像を切り取り、opencv を使用して切り取り、同時に画像のフュージョン部分を切り取ることに注意してください。

# 融合部分图片
def img_mix(img, row_height, col_width, save_path, file):
    mix_num = 3
    # 每行的高度和每列的宽度

    # 分割成4*4就是有
    # 4*3个行融合区域
    # 3*4个列融合区域
    # 一行的融合
    row = 0
    for i in range(mix_num + 1):
        mix_height_start = i * row_height
        mix_height_end = (i + 1) * row_height
        for j in range(mix_num):
            mix_row_path = save_path + '/' + file + '_mix_row_' + str(row) + '.jpg'
            mix_row_start = int(j * col_width + col_width * (1 - mix_percent))
            mix_row_end = int(mix_row_start + col_width * mix_percent * 2)
            # print(mix_height_start, mix_height_end, mix_row_start, mix_row_end)
            mix_row_img = img[mix_height_start:mix_height_end, mix_row_start:mix_row_end]
            cv2.imwrite(mix_row_path, mix_row_img)
            row += 1

    col = 0
    # 一列的融合
    for i in range(mix_num):
        mix_col_start = int(i * row_height + row_height * (1 - mix_percent))
        mix_col_end = int(mix_col_start + row_height * mix_percent * 2)
        for j in range(mix_num + 1):
            mix_col_path = save_path + '/' + file + '_mix_col_' + str(col) + '.jpg'
            mix_width_start = j * col_width
            mix_width_end = (j + 1) * col_width
            # print(mix_col_start, mix_col_end, mix_width_start, mix_width_end)
            mix_col_img = img[mix_col_start:mix_col_end, mix_width_start:mix_width_end]
            cv2.imwrite(mix_col_path, mix_col_img)
            col += 1
小さい絵にカットしたら、ラベル加工部分


対象のデータをxmlファイルから直接読み込みます.読み込みに成功するとコード: get_xml_data.py がtxtファイル形式で保存されます. 保存されたデータは

图片类型(0:子图,1:行融合图,2:列融合图)
小图所处位置(0~15)
小图文件名
大图宽度
大图高度
目标类型
x最小值
x最大值
y最小值
y最大值

読み取り後に得られた結果は次のとおりです
ここに画像の説明を挿入
. 次に、データをさらに分析する必要があります. コード: txt_to_yolo.py
これで、小さな画像の位置、各小さな画像の幅と高さ、およびの幅と高さがわかりました.大きな画像. 次に、小さな画像でターゲットを見つけることができます. 例
:下の画像の幅と高さが 100 で、右上の小さなボックスが
右上部分の中央にあり、幅と高さ10 の場合、小箱の位置情報は
xmin=70, xmax=80 ymin
=20, ymax=
30
ここに画像の説明を挿入
ここで、小区間の位置情報は
xmin=20, xmax=30
ymin=20, ymax=30
となります。

2. ターゲット検出

これは言うまでもありませんが、画像をカットした後、yolov5の画像学習パスと検出パスをカットした画像に変更するだけです。
トレーニング中は融合マップがありますが、検出中は存在しないことに注意してください
(融合マップを検出しなかったため、サブグラフと重なりやすく、比較はマシン検出の結果です) パスを変更: 直接detect
.pydef run() :
ここに画像の説明を挿入
test results:など、以下のパスを変更します。
ここに画像の説明を挿入
ここに画像の説明を挿入

3.融合

これは言うのが難しく、言うのは簡単ではありませんが、
主なことは明確な心を持っていることです

1. 各写真の位置を特定する必要があります (例えば、4*4 にカットすると、合計 16 の位置があります)
2. 各位置に応じて、各写真の検出結果 (txt ファイル) の内容は、大きな画像の対応する位置に、たとえば位置が右上隅 (0, 3) の場合、画像内の検出結果の x 値を追加する必要があります (3 * 大きな画像の幅/4)。 )、その後、yolov5 ラベル形式に再変換されます

それくらい?
融合結果
ここに画像の説明を挿入

4. 結果観察

前述のように、ここでのトレーニングと検出は小さな画像に基づいているため、結果を直接観察する (画像上のフレームを検出する) ことは容易ではありません。次に、ImageDraw を使用して元の画像にフレーム結果を直接描画でき
ます
融合されたtxtファイルの結果は悪くありません
ここに画像の説明を挿入

トレーニング結果

トレーニング結果を見て
ここに画像の説明を挿入

他の

いくつかの同様のプロジェクト yolov5-tph を参照することもできます
: https://github.com/Gumpest/YOLOv5-Multibackbone-Compression
yolov-z
小さなターゲット検出レイヤーに他に追加できるもの (それは一般的ではありません。試してみてください)トレーニング時間を増やすこと以外はアウトです。また、効果も一般的です)

関連ドキュメント:

設定ファイル:config.py
切り抜き画像:cut_image.py
xmlデータ読み込み:get_xml_data.py
切り抜きラベルデータ:txt_to_yolo.py
融合絵:join_image.py
元絵枠:draw_box.py
メイン関数:main.py
ダウンロードアドレス ①
ファイルのダウンロード住所②

おすすめ

転載: blog.csdn.net/qq_43622870/article/details/124984295