セマンティックセグメンテーション Ground Truth (GT) に基づいて yolov5 画像セグメンテーション ラベルを変換 (路面水検出の例)

セマンティックセグメンテーション Ground Truth (GT) に基づいて yolov5 画像セグメンテーション ラベルを変換 (路面水検出の例)

概要

開発者は、問題のセグメンテーション タスクを実行するために yolov5 を要求しているため、yolov5 チームは開発者の問題解決を実際に支援しています。v6.0 バージョン以降、最新のソリューションがチュートリアルとともに開始されます。

画像-20230128172549462

以前は、改良された yolo を使用してセグメンテーション ヘッドを追加してターゲットの検出とセグメンテーションを実現する方法がありましたが、最新の v7.0 バージョンでは非常に良い効果があり、yolov8 もセグメンテーションに大きな打撃を与えています

画像-20230128172654729

画像

したがって、yolo を使用してターゲット検出を完了することも、着陸プロジェクトのオプションの 1 つであり、yolo の生態系は、着陸や試験的な検出の実現により適しています。ただし、現在の公開データ セットのほとんどは他のセグメンテーション ドメイン モデルを使用しており、当然ラベルも他のモデルに適応されます。これはJishi プラットフォームで競技をやっていたときに思いついたのですが、道路エリアはターゲット検出を使ったほうが省力になるのではないかと思ったのですが、セグメンテーションのデータを教えていただきました。

画像

画像

GT 画像タグを yolo の形式に変換しようとしましたが、長い間探しても良い解決策が見つからなかったので、以前のターゲット検出の経験に基づいて修正してみまし

プロセス

分割された領域に対応する json 形式などの形式のラベルがないため、Polygon のラベル形式として理解できる GT に従って対応する座標を見つける必要があり、各変曲点は labelimg でマークされているため、輪郭検出により大まかな輪郭を取得するために必要な座標点、yolo で必要な形式に変換

1、查找分割区域,
2、获取分割区域的轮廓坐标
3、精简坐标点
4、转存txt

上記の操作はすべて OpenCV に基づいています

読んで処理する

シングルチャンネルのグレースケール画像に変換し、二値化画像を処理して、画像に自動的に閾値を変換させます。

cv2.threshold (src, thresh, maxval, type)

src:源图片,必须是单通道
thresh:阈值,取值范围0~255
maxval:填充色,取值范围0~255
type:阈值类型,具体见下表

しきい値の種類:

しきい値 パラメータの種類 閾値より小さいピクセル しきい値を超えたピクセル
0 cv2.THRESH_BINARY 0に設定 塗りつぶしの色を設定する
1 cv2.THRESH_BINARY_INV 塗りつぶしの色を設定する 0に設定
2 cv2.THRESH_TRUNC 元の色を維持する グレーに設定します
3 cv2.THRESH_TOZERO 0に設定 元の色を維持する
4 cv2.THRESH_TOZERO_INV 元の色を維持する 0に設定

画像-20230129101726731

ここでは自動しきい値調整を使用したため、0 ~ 255 の範囲を指定するだけで済みます。

gray_img = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
ret,bin_img = cv2.threshold(gray_img,0,255,cv2.THRESH_BINARY+cv2.THRESH_OTSU)

輪郭をクエリして座標点を取得します

GT タグのラベル付けは非常に細かく、多くのエッジ点が存在するため、シングル チャネル画像は輪郭点クエリのためのエッジ検出アルゴリズムに送信されます。点推定、またはフィルタ方法へ

cv2.findContours(image, mode, method[, offset])

手法:輪郭近似手法には以下の手法があります。

cv2.CHAIN_APPROX_NONE:存储所有的轮廓点
cv2.CHAIN_APPROX_SIMPLE:压缩水平,垂直和对角线段,只留下端点。 例如矩形轮廓可以用4个点编码。
cv2.CHAIN_APPROX_TC89_L1,cv2.CHAIN_APPROX_TC89_KCOS:使用Teh-Chini chain近似算法

テストした結果、cv2.CHAIN_APPROX_TC89_KCOS メソッドの方がニーズに合致しています。以下は、いくつかのメソッドの比較表です。

元の画像

画像-20230129102601475

cv2.CHAIN_APPROX_NONE

画像-20230129103241865

cv2.CHAIN_APPROX_SIMPLE

画像-20230129103345849

cv2.CHAIN_APPROX_TC89_L1

画像-20230129103557153

cv2.CHAIN_APPROX_TC89_KCOS

画像-20230129103640467

yolo のラベル形式は、曲がり角や長辺にマーク点を追加する形式なので、隣接する点はあまり必要なく、大まかな輪郭を与えるだけで済みますが、上記と比較して最も適しているのは cv2.CHAIN_APPROX_TC89_KCOS 近似法です。

しかし、最終結果のグラフからは、まだ不要な点がいくつかあるため、x または y の隣接する点の変化がしきい値を超えた場合は保持され、そうでない場合はマークされず、グラフとして使用されないという単純な原則を選択します。セグメンテーションポイントしきい値は固定されていません。30に設定すると、効果は次のようになります。

画像-20230129102920513

コードの上記の部分

cnt,hit = cv2.findContours(bin_img,cv2.RETR_TREE,cv2.CHAIN_APPROX_TC89_KCOS)
cv2.drawContours(img1,cnt,-1,(0,255,0),5)
cnt = list(cnt)
for j in cnt:
    result = []
    pre = j[0]
    for i in j:
        if abs(i[0][0] - pre[0][0]) > 30 or abs(i[0][1] - pre[0][1]) > 30:
            pre = i
            temp = list(i[0])
            #根据yolo的归一化方式,x,y分别除以原图的宽和高
            temp[0] /= W
            temp[1] /= H
            result.append(temp)
            cv2.circle(img1,i[0],1,(0,0,255),2)

テキストを計算してダンプする

カテゴリごとの座標に応じて格納されており、座標が多くなる場合もあるため一度配列を記述する必要があります。複数のカテゴリを個別に処理する必要がある場合、最初に書かれた「0」が現在のカテゴリです。

f.write("0 ")
for line in result:
    line = str(line)[1:-2].replace(",","")
    # print(line)
    f.write(line+" ")
f.write("\n")

効果デモ: https: //live.csdn.net/v/271857

完全なコード: https://github.com/magau123/CSDN/blob/master/GT2yolo-seg.py

おすすめ

転載: blog.csdn.net/charles_zhang_/article/details/128786621