長方形のボックスとキーポイントに labelme でラベルを付けた json ファイルを yolov5-face 学習用の txt 形式に変換します

目次

labelme でマークした json ファイルは次のようになります。注釈には、長方形のボックスとポイントの 2 種類があります。

変換したいtxt形式は次のようになります。

次のように json 形式を txt に変換します。

txt からの注釈結果の表示


こちらのブロガーさんを参考に変更を加えました。(メッセージ数 484 件) LabelMe ラベル付き json から txt 形式への変換チュートリアル_非破壊テスト初心者 Baibai のブログ - CSDN ブログ

labelme でマークした json ファイルは次のようになります。注釈には、長方形のボックスとポイントの 2 種類があります。

変換したいtxt形式は次のようになります。

それぞれ、ターゲット カテゴリ番号 (0 から始まる)、長方形ボックスの中心点の正規化された x 座標、長方形ボックスの中心点の正規化された y 座標、正規化された長方形ボックスの幅 w 、正規化された長方形ボックスの高さ hを表します。point 1 の x 座標は正規化されpoint 1 の y 座標は正規化されます...point 2 3 4 など。

[点1、2、3、4は順に(左上、右上、右下、左下)となり、四角枠の座標とキーポイントの座標は正規化する必要があります]

[正規化を達成するにはどうすればよいですか? ? 中心点x座標/画像幅、y座標/画像高さ、長方形枠幅/画像幅、高さ/画像高さ、キーポイント水平/画像幅で割った値、キーポイント縦座標/画像高さ----以下変換ありコードに反映されているので、わからない場合はよく見てください〜]

次のように json 形式を txt に変換します。

# -*- coding: UTF-8 -*-
import json
import os
import cv2

img_folder_path = 'datasets/500'  # 图片存放文件夹
folder_path = 'datasets/picbiaozhu'  # 标注数据的文件地址
txt_folder_path = 'datasets/txtresults'  # 转换后的txt标签文件存放的文件夹


# 保存为相对坐标形式 :label x_center y_center w h
def relative_coordinate_txt(img_name, json_d, img_path):
    src_img = cv2.imread(img_path)
    # h, w = src_img.shape[:2]
    h, w, c = src_img.shape
    txt_name = img_name.split(".")[0] + ".txt"
    txt_path = os.path.join(txt_folder_path, txt_name)
    print(txt_path)
    with open(txt_path, 'w') as f:
        for item in json_d["shapes"]:
            if item['shape_type'] == 'rectangle' and item['label'] == 'nameplate':
                point = item['points']
                x_center = (point[0][0] + point[1][0]) / 2
                y_center = (point[0][1] + point[1][1]) / 2
                width = point[1][0] - point[0][0]
                height = point[1][1] - point[0][1]
                # print(x_center)
                f.write(" {} ".format(0))
                f.write(" {} ".format(x_center / w))
                f.write(" {} ".format(y_center / h))
                f.write(" {} ".format(width / w))
                f.write(" {} ".format(height / h))
                continue

            keypoint = item['points']
            x = keypoint[0][0]
            y = keypoint[0][1]
            f.write(" {} ".format(x / w))
            f.write(" {} ".format(y / h))
        f.write(" \n")
    print('finish!')


for jsonfile in os.listdir(folder_path):
    # os.listdir用来返回指定文件夹包含的文件或文件夹的名字的列表
    temp_path = os.path.join(folder_path, jsonfile)
    print("json_path:\t",  temp_path)
    jsonfile_path = temp_path
    with open(jsonfile_path, "r", encoding='utf-8') as fff:
        json_d = json.load(fff, strict=False)
        img_name = json_d['imagePath'].split("\\")[-1].split(".")[0] + ".jpg"
        img_path = os.path.join(img_folder_path, img_name)
        print("img_path:\t", img_path)
        retname = img_name.replace(".jpg", ".txt")
        retpath = os.path.join(txt_folder_path, retname)
        if os.path.exists(retpath):
            continue
        else:
            relative_coordinate_txt(img_name, json_d, img_path)

txt からの注釈結果の表示

# -*- coding: UTF-8 -*-
import json
import os
import cv2
from cv2 import FONT_HERSHEY_SIMPLEX

img_folder_path = 'testimgandjson'  # 图片存放文件夹
folder_path = 'testimgandjson\img002.json'  # 存放标注数据的文件地址
txt_folder_path = "TXTfiles"  # 转换后的txt标签文件存放的文件夹


# 相对坐标格式
def show_label_from_txt(img_path, txt_path):
    window_name = ('src')
    cv2.namedWindow(window_name, cv2.WINDOW_FREERATIO)
    src_img = cv2.imread(img_path)
    h, w = src_img.shape[:2]
    font = cv2.FONT_HERSHEY_SIMPLEX
    with open(txt_path, "r", encoding='UTF-8') as f:
        line = f.readline()
        # 该函数返回的是字符串
        newline = line[1: ]
        data = newline.split('  ')
        # 返回值是字符串列表
        label = data[0]
        cx = float(data[1])
        cy = float(data[2])
        ww = float(data[3])
        hh = float(data[4])
        x1 = int(cx * w - 0.5 * ww * w)
        x2 = int(cx * w + 0.5 * ww * w)
        y1 = int(cy * h - 0.5 * hh * h)
        y2 = int(cy * h + 0.5 * hh * h)
        p1 = (x1, y1)
        p2 = (x2, y2)
        cv2.rectangle(src_img, p1, p2, (0, 255, 0), 5)
        # 图片,顶点1,顶点2,矩形颜色,组成矩形的线粗细若为负值如-1表示绘制一个填充矩形
        cv2.putText(src_img, label, p1, FONT_HERSHEY_SIMPLEX, 200, (255, 0, 0), 5)
        # 图片,要绘制的文本字符串,文本字符串左下角的坐标,字体类型,字体大小,文本颜色,线宽
        x00 = float(data[5])*w
        y00 = float(data[6])*h
        x01 = float(data[7])*w
        y01 = float(data[8])*h
        x11 = float(data[9])*w
        y11 = float(data[10])*h
        x10 = float(data[11])*w
        y10 = float(data[12])*h
        coordinates = [[x00,y00],[x01,y01],[x11,y11],[x10,y10]]
        for coo in coordinates:
            cv2.circle(src_img,(int(coo[0]),int(coo[1])),25,(0,255,0),-5)
        #图像,圆心坐标,半径,圆边框颜色,正值表示线宽负值表示填充一个圆形
        cv2.imshow(window_name, src_img)
        cv2.waitKey(0)
    cv2.destroyAllWindows()
    return


i = 0
for txtfile in os.listdir(txt_folder_path):
    txt_path = os.path.join(txt_folder_path, txtfile)
    # 一直报错utf-8,原因是我txt文件没有放对位置,地址没有写对,导致
    # for循环第一次循环没找到txt文件解码失败。
    i += 1
    if i > 15:
        break
    # 如果是一个子目录就继续
    if os.path.isdir(txt_path):
        continue
    print("txt_path:\t", txt_path)
    img_name = txtfile.split("\\")[-1].split(".")[0] + ".jpg"
    img_path = os.path.join(img_folder_path, img_name)
    show_label_from_txt(img_path, txt_path)

おすすめ

転載: blog.csdn.net/qq_44133071/article/details/129844473