Data labeling for PaddleDetect image target detection model training - using labelme for labeling

0 Preface

When training the PaddleDetect image detection model, it is necessary to manually label the data set. The following will take the truck detection as an example, and record the detailed process of labeling with labelme, in case you forget it in the future.

Please download the files used in this article here: https://download.csdn.net/download/loutengyuan/87616492

1 labelme environment construction

labelme is a graphical image annotation tool, which is written in Python and uses Qt for its graphical interface. To put it bluntly, it has an interface, like software, and can be interacted with, but it is started by the command line, which is a little more troublesome than using software. Its interface is as follows:
insert image description here

Note: I have done Sinicization of the interface here. It was originally in English, and the Sinicization files will be provided below.

1.1 labelme tool installation

Please open the cmd command window first, and then enter the following command to install:

# -i 是指定国内镜像源,提高安装速度
pip install labelme -i https://mirror.baidu.com/pypi/simple

insert image description here
Check if it is installed with the following command:

pip list

insert image description here

1.2 Chinese labelme

Replace the labelme Chinese file (app.py file in the download directory) with the following directory (this is based on your actual installation directory):

C:\Users\Administrator\AppData\Local\Programs\Python\Python310\Lib\site-packages\labelme

insert image description here

2 Labeling operation process

Open the downloaded file, you can see the following files:

  • truck_detect: the picture to be marked
  • app.py: labelme Chinese file
  • labels.txt: label list
  • Double-click to open the annotation tool.bat: start the script
    insert image description here

2.1 Open the annotation tool

Originally, the labelme software was launched through the command line. Here I put this command into the double- click to open the labeling tool.bat file, so just double-click this script to open the labelme tool. The content of the startup script is as follows:

:: 进入当前目录
cd  %~dp0
labelme truck_detect --labels labels.txt
pause

2.2 Turn on the auto save option

  • Select File -> Save Automatically to automatically save the option
    insert image description here

new dimension

Select the Draw Rectangle or Draw Polygon option
insert image description here
to perform the following steps, install the label type to mark the position of each area in the picture, and then click Next, the drawn area will be automatically saved:
insert image description here

2.3 Edit/modify annotation

If the label is wrongly selected or the area needs to be adjusted, you can click Edit to select, select the area to be edited to modify, or right-click to select Edit Label to modify.
insert image description here

2.4 Annotate files

The marked files and pictures are saved in the truck_detect folder:
insert image description here
the label file is in json format, and the content is as follows:

{
    
    
  "version": "5.1.1",
  "flags": {
    
    },
  "shapes": [
    {
    
    
      "label": "整车侧面",
      "points": [
        [
          96.73611111111113,
          66.625
        ],
        [
          446.0416666666667,
          290.23611111111114
        ]
      ],
      "group_id": null,
      "shape_type": "rectangle",
      "flags": {
    
    }
    },
    {
    
    
      "label": "车头侧面",
      "points": [
        [
          101.59722222222224,
          70.79166666666666
        ],
        [
          299.5138888888889,
          294.40277777777777
        ]
      ],
      "group_id": null,
      "shape_type": "rectangle",
      "flags": {
    
    }
    },
    {
    
    
      "label": "车轮侧面",
      "points": [
        [
          177.29166666666669,
          188.84722222222223
        ],
        [
          431.45833333333337,
          288.84722222222223
        ]
      ],
      "group_id": null,
      "shape_type": "rectangle",
      "flags": {
    
    }
    },
    {
    
    
      "label": "车身侧面",
      "points": [
        [
          290.48611111111114,
          70.79166666666666
        ],
        [
          439.09722222222223,
          279.125
        ]
      ],
      "group_id": null,
      "shape_type": "rectangle",
      "flags": {
    
    }
    }
  ],
  "imagePath": "81675.jpg_800x533.jpg",
  "imageData": "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",
  "imageHeight": 327,
  "imageWidth": 490
}

3 format conversion

Commonly used target detection datasets come in two formats, VOC and COCO.

3.1 Convert to COCO format

If you use the COCO format, it is recommended to use x2coco in PaddleDetection to convert the marked file into a COCO format dataset. The conversion code is as follows:

python tools/x2coco.py \
                --dataset_type labelme \
                --json_input_dir ./labelme_annos/ \
                --image_input_dir ./labelme_imgs/ \
                --output_dir ./cocome/ \
                --train_proportion 0.8 \
                --val_proportion 0.2 \
                --test_proportion 0.0

3.2 Convert to VOC format

This project uses the dataset in VOC format, use the following code to convert the dataset into VOC2007 format:

import os
import numpy as np
import codecs
import json
from glob import glob
import cv2
import shutil

# 标签路径
labelme_path = "D:/DataProcess/vehicle/truck_detect/truck_detect/"  # 原始labelme标注数据路径
saved_path = "D:/DataProcess/vehicle/truck_detect/truck_detect_voc/"  # 保存路径

# 将中文标签名称转换成英文字母
label_translate_dict = {
    
    
    "车头正面": "head_front",
    "车头侧面": "head_side",
    "车身侧面": "body_side",
    "车轮侧面": "wheel_side",
    "整车侧面": "vehicle_side",
    "工程车": "vehicle_side" # engine_truck
}

label_txt = ["__ignore__", "_background_"]

# 创建要求文件夹
if not os.path.exists(saved_path + "Annotations"):
    os.makedirs(saved_path + "Annotations")
if not os.path.exists(saved_path + "JPEGImages/"):
    os.makedirs(saved_path + "JPEGImages/")

# 获取待处理文件
files = glob(labelme_path + "*.json")
files = [i.split("\\")[-1].split(".json")[0] for i in files]
total_len = len(files)
total_idx = 0

out_count = 0
skip_count = 0
err_count = 0

# 读取标注信息并写入 xml
for json_file_ in files:
    total_idx += 1
    if " " in json_file_:
        continue
    json_filename = labelme_path + json_file_ + ".json"
    img_filename = labelme_path + json_file_ + ".jpg"
    if not os.path.exists(json_filename) or not os.path.exists(img_filename):
        continue
    json_file = json.load(open(json_filename, "r", encoding="utf-8"))

    if total_idx % 100 == 0:
        print("进度:{}".format((total_idx / total_len) * 100))

    imagePath = json_file["imagePath"]
    if json_file_ not in imagePath:
        err_count += 1
        print("imagePath error fileName = {}    imagePath = {}".format(json_file_, imagePath))
        continue

    height, width, channels = cv2.imread(img_filename).shape
    success_count = 0
    xml_filename = saved_path + "Annotations/" + json_file_ + ".xml"
    with codecs.open(xml_filename, "w", "utf-8") as xml:
        xml.write('<annotation>\n')
        xml.write('\t<folder>' + 'UAV_data' + '</folder>\n')
        xml.write('\t<filename>' + json_file_ + ".jpg" + '</filename>\n')
        xml.write('\t<source>\n')
        xml.write('\t\t<database>The UAV autolanding</database>\n')
        xml.write('\t\t<annotation>UAV AutoLanding</annotation>\n')
        xml.write('\t\t<image>flickr</image>\n')
        xml.write('\t\t<flickrid>NULL</flickrid>\n')
        xml.write('\t</source>\n')
        xml.write('\t<owner>\n')
        xml.write('\t\t<flickrid>NULL</flickrid>\n')
        xml.write('\t\t<name>ChaojieZhu</name>\n')
        xml.write('\t</owner>\n')
        xml.write('\t<size>\n')
        xml.write('\t\t<width>' + str(width) + '</width>\n')
        xml.write('\t\t<height>' + str(height) + '</height>\n')
        xml.write('\t\t<depth>' + str(channels) + '</depth>\n')
        xml.write('\t</size>\n')
        xml.write('\t\t<segmented>0</segmented>\n')

        for multi in json_file["shapes"]:
            points = np.array(multi["points"])
            xmin = min(points[:, 0])
            xmax = max(points[:, 0])
            ymin = min(points[:, 1])
            ymax = max(points[:, 1])

            if "未知" in multi["label"]:
                break
            for key in label_translate_dict.keys():
                if key in multi["label"]:
                    label = label_translate_dict[key]
                    break
            if label is None:
                continue
            if label not in label_txt:
                label_txt.append(label)

            if xmax <= xmin:
                continue
            elif ymax <= ymin:
                continue
            elif (xmax - xmin) * (ymax - ymin) < 1000:
                continue
            else:
                xml.write('\t<object>\n')
                xml.write('\t\t<name>' + label + '</name>\n')
                xml.write('\t\t<pose>Unspecified</pose>\n')
                xml.write('\t\t<truncated>1</truncated>\n')
                xml.write('\t\t<difficult>0</difficult>\n')
                xml.write('\t\t<bndbox>\n')
                xml.write('\t\t\t<xmin>' + str(xmin) + '</xmin>\n')
                xml.write('\t\t\t<ymin>' + str(ymin) + '</ymin>\n')
                xml.write('\t\t\t<xmax>' + str(xmax) + '</xmax>\n')
                xml.write('\t\t\t<ymax>' + str(ymax) + '</ymax>\n')
                xml.write('\t\t</bndbox>\n')
                xml.write('\t</object>\n')
                # print(total_idx, total_len, json_filename, xmin, ymin, xmax, ymax, label)
                success_count += 1
        xml.write('</annotation>')

    if success_count > 0:
        shutil.copy(img_filename, saved_path + "JPEGImages/")
        out_count += 1
    else:
        skip_count += 1
        if os.path.exists(xml_filename):
            os.remove(xml_filename)

# 写标签文件
labels_txt_writer = open(saved_path + '/labels.txt', 'w')
for text in label_txt:
    labels_txt_writer.write(text + "\n")
labels_txt_writer.close()

print("-------------------------------- Finished  --------------------------------")
print("out_count = {}".format(out_count))
print("skip_count = {}".format(skip_count))
print("err_count = {}".format(err_count))
print("label_txt = {}".format(label_txt))

3.3 Output label area

The following script is used to parse the label json file and crop or draw the result into the image separately to view the labeling effect:

import os
import numpy as np
import json
from glob import glob
import cv2
from PIL import Image, ImageDraw, ImageFont

labelme_path = "D:/DataProcess/vehicle/truck_detect/truck_detect/"  # 原始labelme标注数据路径
# 输出文件夹路径
outputPath = "D:/DataProcess/vehicle/predict_output/"

files = glob(labelme_path + "*.json")
files = [i.split("\\")[-1].split(".json")[0] for i in files]
files_size = len(files)


# 将区域裁剪单独保存
def clip_save():
    file_idx = 0
    for json_file_ in files:
        file_idx += 1
        if " " in json_file_:
            continue
        json_filename = labelme_path + json_file_ + ".json"
        img_filename = labelme_path + json_file_ + ".jpg"
        if not os.path.exists(json_filename) or not os.path.exists(img_filename):
            continue
        json_file = json.load(open(json_filename, "r", encoding="utf-8"))
        # image = cv2.imread(img_filename)
        image = cv2.imdecode(np.fromfile(img_filename, dtype=np.uint8), -1)
        # height, width, channels = image.shape

        # "车头正面", "车头侧面", "车身侧面", "车轮侧面", "整车侧面", "工程车"
        for label_name in ["车头正面", "车头侧面"]:
            outputLabelPath = outputPath + label_name + "/"
            if not os.path.exists(outputLabelPath):
                os.makedirs(outputLabelPath)
            idx = 0
            for multi in json_file["shapes"]:
                points = np.array(multi["points"])
                xmin = min(points[:, 0])
                xmax = max(points[:, 0])
                ymin = min(points[:, 1])
                ymax = max(points[:, 1])

                #     "车头正面", "车头侧面", "车身侧面", "车轮侧面", "整车侧面"
                label = multi["label"]
                if label_name not in label:
                    continue

                if xmax <= xmin:
                    continue
                elif ymax <= ymin:
                    continue
                elif (xmax - xmin) * (ymax - ymin) < 1000:
                    continue
                else:
                    print("{}/{} {} {} {} {} {} {}".format(file_idx, files_size, json_filename, xmin, ymin, xmax, ymax,
                                                           label))
                    # 将主体区域裁剪后保存到输出文件夹 #参数1 是高度的范围,参数2是宽度的范围
                    img_crop = image[int(ymin):int(ymax), int(xmin):int(xmax)]
                    if idx == 0:
                        out_image_file = outputLabelPath + json_file_ + ".jpg"
                    else:
                        out_image_file = outputLabelPath + "crop_" + str(idx) + "_" + json_file_ + ".jpg"
                    # cv2.imwrite(out_image_file, img_crop)
                    cv2.imencode('.jpg', img_crop)[1].tofile(out_image_file)

                    idx += 1


# 将结果绘制到一张图片
def draw_save():
    file_idx = 0
    for json_file_ in files:
        file_idx += 1
        if " " in json_file_:
            continue
        json_filename = labelme_path + json_file_ + ".json"
        img_filename = labelme_path + json_file_ + ".jpg"
        if not os.path.exists(json_filename) or not os.path.exists(img_filename):
            continue
        json_file = json.load(open(json_filename, "r", encoding="utf-8"))
        # image = cv2.imread(img_filename)
        image = cv2.imdecode(np.fromfile(img_filename, dtype=np.uint8), -1)[:, :, ::-1]
        if isinstance(image, np.ndarray):
            image = Image.fromarray(image)
        # height, width, channels = image.shape
        is_success = False
        for multi in json_file["shapes"]:
            points = np.array(multi["points"])
            xmin = min(points[:, 0])
            xmax = max(points[:, 0])
            ymin = min(points[:, 1])
            ymax = max(points[:, 1])

            #     "车头正面", "车头侧面", "车身侧面", "车轮侧面", "整车侧面"
            label = multi["label"]
            tag = False
            for text in ["车头正面"]:
                if text in label:
                    tag = True
                    break
            if not tag:
                continue

            if xmax <= xmin:
                continue
            elif ymax <= ymin:
                continue
            else:
                is_success = True
                print("{}/{} {} {} {} {} {} {}".format(file_idx, files_size, json_filename, xmin, ymin, xmax, ymax,
                                                       label))
                draw = ImageDraw.Draw(image)
                font_size = 36
                # simfang.ttf 这个文件在下载包中有
                font = ImageFont.truetype("./simfang.ttf", font_size, encoding="utf-8")
                text = "标签:{}".format(multi["label"])
                th = font_size
                tw = font.getsize(text)[0]
                # tw = int(len(result["rec_docs"]) * font_size) + 60
                start_y = max(0, ymin - th)

                draw.rectangle(
                    [(xmin + 1, start_y), (xmin + tw + 1, start_y + th)], fill=(0, 102, 255))

                draw.text((xmin + 1, start_y), text, fill=(255, 255, 255), font=font)

                draw.rectangle(
                    [(xmin, ymin), (xmax, ymax)], outline=(255, 0, 0), width=2)

        if is_success:
            # image.show(img_filename)

            os.makedirs(outputPath, exist_ok=True)
            output_path = os.path.join(outputPath, json_file_ + ".jpg")

            image.save(output_path, quality=95)


if __name__ == '__main__':
    # 将结果单独裁剪保存
    clip_save()

    # # 将结果绘制到同一张图片上保存
    # draw_save()

Guess you like

Origin blog.csdn.net/loutengyuan/article/details/129751419