学习系列二:常用目标检测的格式转换脚本文件txt,json等

常用目标检测的格式转换脚本文件txt,json等


文章目录

  • 常用目标检测的格式转换脚本文件txt,json等
  • 前言
  • 一、json格式转yolo的txt格式
  • 二、yolov8的关键点labelme打的标签json格式转可训练的txt格式
  • 三、yolo的目标检测txt格式转coco数据集标签的json格式
  • 四、xml格式转yolo数据集标签的txt格式
  • 五、根据yolo的目标检测训练的最好权重推理图片
  • 六、根据yolo标签的txt文件提取某一个特征类别的标签, 并在原图上进行绘制
  • 七、根据yolo标签的txt文件提取某一个特征类别的标签, 并在原图上进行绘制


前言

⭐️ ⭐️ ⭐️ 还在完善中 ⭐️ ⭐️ ⭐️

本节主要介绍在目标检测领域内,常用的格式转换脚本


一、json格式转yolo的txt格式

json格式的目标检测数据集标签格式转yolo目标检测的标签txt的格式

代码如下(示例): 主要修改 classes, json_folder_path, output_dir

"""
目标检测的 json --> 转为 yolo的txt
"""
import json
import os


def convert(size, box):
    dw = 1. / size[0]
    dh = 1. / size[1]
    x = (box[0] + box[2]) / 2.0
    y = (box[1] + box[3]) / 2.0
    w = box[2] - box[0]
    h = box[3] - box[1]
    x = x * dw
    w = w * dw
    y = y * dh
    h = h * dh

    return (x, y, w, h)


def decode_json(json_path, output_dir, classes):
    with open(json_path, 'r', encoding='utf-8') as f:
        data = json.load(f)

    base_name = os.path.splitext(os.path.basename(data['imagePath']))[0]
    txt_path = os.path.join(output_dir, base_name + '.txt')
    with open(txt_path, 'w', encoding='utf-8') as txt_file:
        for shape in data['shapes']:
            if shape['shape_type'] == 'rectangle':
                label = shape['label']
                if label not in classes:
                    continue
                cls_id = classes.index(label)
                points = shape['points']
                x1, y1 = points[0]
                x2, y2 = points[1]  # Assuming the points are diagonal

                bb = convert((data['imageWidth'], data['imageHeight']), [x1, y1, x2, y2])
                txt_file.write(f"{cls_id} {' '.join(map(str, bb))}\n")


if __name__ == "__main__":
    # 指定YOLO类别
    classes = ['loose', 'un-loose']  # 根据实际类别名称进行修改
    # JSON格式的标签文件路径
    json_folder_path = './json'  # 替换为实际的JSON文件夹路径
    # 转换为YOLO格式的TXT标签文件存储路径
    output_dir = './txt'  # 替换为实际的TXT保存路径

    if not os.path.exists(output_dir):
        os.makedirs(output_dir)

    json_files = [file for file in os.listdir(json_folder_path) if file.endswith('.json')]

    for json_file in json_files:
        json_path = os.path.join(json_folder_path, json_file)
        decode_json(json_path, output_dir, classes)

    # 将类别名称写入classes.txt文件
    with open(os.path.join(output_dir, 'classes.txt'), 'w', encoding='utf-8') as file:
        for class_name in classes:
            file.write(class_name + '\n')

    print(f"Conversion completed. TXT files are saved in {output_dir}")

二、yolov8的关键点labelme打的标签json格式转可训练的txt格式

yolov8的关键点labelme打的标签json格式转可训练的txt格式

代码如下(示例):只需修改 class_list, keypoint_list, img_list

将labelme标注关键点数据集的 json文件转为 yolo 格式
采用 labelme进行标注
"""
import os
import cv2
import numpy as np
import matplotlib.pyplot as plt
import glob
import json
import tqdm


# 物体类别
class_list = ["fks"]
# 关键点的顺序
keypoint_list = ["P1", "P2", "P3", "P4"]


def json_to_yolo(img_data, json_data):
    h, w = img_data.shape[:2]
    # 步骤:
    # 1. 找出所有的矩形,记录下矩形的坐标,以及对应group_id
    # 2. 遍历所有的head和tail,记下点的坐标,以及对应group_id,加入到对应的矩形中
    # 3. 转为yolo格式

    rectangles = {}
    # 遍历初始化
    for shape in json_data["shapes"]:
        label = shape["label"]              # pen, head, tail
        group_id = shape["group_id"]        # 0, 1, 2, ...
        points = shape["points"]            # x,y coordinates
        shape_type = shape["shape_type"]

        # 只处理矩形
        if shape_type == "rectangle":
            if group_id not in rectangles:
                rectangles[group_id] = {
                    "label": label,
                    "rect": points[0] + points[1],  # Rectangle [x1, y1, x2, y2]
                    "keypoints_list": []
                }
    # 遍历更新,将点加入对应group_id的矩形中
    for keypoint in keypoint_list:
        for shape in json_data["shapes"]:
            label = shape["label"]
            group_id = shape["group_id"]
            points = shape["points"]
            # 如果匹配到了对应的keypoint
            if label == keypoint:
                rectangles[group_id]["keypoints_list"].append(points[0])
    
    # 转为yolo格式
    yolo_list = []
    for id, rectangle in rectangles.items():
        result_list = []
        label_id = class_list.index(rectangle["label"])
        # x1, y1, x2, y2
        x1, y1, x2, y2 = rectangle["rect"]
        # center_x, center_y, width, height
        center_x = (x1+x2)/2
        center_y = (y1+y2)/2
        width = abs(x1-x2)
        height = abs(y1-y2)
        # normalize
        center_x /= w
        center_y /= h
        width /= w
        height /= h

        # 保留6位小数
        center_x = round(center_x, 6)
        center_y = round(center_y, 6)
        width = round(width, 6)
        height = round(height, 6)


        # 添加 label_id, center_x, center_y, width, height
        result_list = [label_id, center_x, center_y, width, height]

        # 添加 p1_x, p1_y, p1_v, p2_x, p2_y, p2_v
        for point in rectangle["keypoints_list"]:
            x, y = point
            x, y = int(x), int(y)
            # normalize
            x /= w
            y /= h
            # 保留6位小数
            x = round(x, 6)
            y = round(y, 6)
            
            result_list.extend([x, y, 2])

        yolo_list.append(result_list)
    
    return yolo_list


# 获取所有的图片./fks-pose/images/train/
img_list = glob.glob(r"C:\Users\Administrator\Desktop\images/*.jpg")

for img_path in tqdm.tqdm(img_list):
        
    img = cv2.imdecode(np.fromfile(img_path, dtype=np.uint8), -1)

    json_file = img_path.replace('jpg', 'json')

    # 对中文路径下进行遍历
    with open(json_file, 'r', encoding='utf-8') as json_file:
    # with open(json_file) as json_file:
        json_data = json.load(json_file)

    yolo_list = json_to_yolo(img, json_data)
    
    yolo_txt_path = img_path.replace('jpg', 'txt')
    with open(yolo_txt_path, "w") as f:
        for yolo in yolo_list:
            for i in range(len(yolo)):
                if i == 0:
                    f.write(str(yolo[i]))
                else:
                    f.write(" " + str(yolo[i]))
            f.write("\n")

三、yolo的目标检测txt格式转coco数据集标签的json格式

json格式的目标检测数据集标签格式转yolo目标检测的标签txt的格式
coco数据集格式如下:
├── data
│ ├── coco
│ │ ├── annotations
│ │ │ ├── instances_train2017.json
│ │ │ ├── instances_val2017.json
│ │ ├── train2017
│ │ ├── val2017
│ │ ├── test2017
————————————————

  • 我们需要对yolo的数据集的训练集(train)、验证集(val)、测试集(test)标签分别进行转换生成coco数据集的标签格式(图片相对是不变的)instances_train2017.json、 instances_val2017.json(这里不需要对应的test的标签)
  • 在回顾说明一下需要转换的,和保持相对不变的
    保持相对不变的:
  • linhuo/images/train的图片直接复制到train2017
  • linhuo/images/val的图片直接复制到val2017
  • linhuo/images/test的图片直接复制到test2017
  • 需要改变的是:
  • linhuo/labels/train的所有标签需要转换成 instances_train2017.json(coco格式)
  • linhuo/labels/vla的所有标签需要转换成instances_val2017.json(coco格式)
    ————————————————

代码如下(示例):

"""
yolo标签:
yolo数据集的标注文件是.txt文件,在label文件夹中每一个.txt文件对应数据集中的一张图片
其中每个.txt文件中的每一行代表图片中的一个目标。
coco标签:
而coco数据集的标注文件是.json文件,全部的数据标注文件由三个.json文件组成:train.json val.json test.json,
其中每个.json文件中包含全部的数据集图片中的所有目标(注意是所有目标不是数据集中的所有张图片)
准备工作:
1. 在根目录下创建coco文件格式对应的文件夹
dataset_coco:
    annotations
    images
    labels
    classes.txt(每一行是自定义数据集中的一个类别)

YOLO 格式的数据集转化为 COCO 格式的数据集
--root_dir 输入根路径
--save_path 保存文件的名字(没有random_split时使用)
--random_split 有则会随机划分数据集,然后再分别保存为3个文件。
--split_by_file 按照 ./train.txt ./val.txt ./test.txt 来对数据集进行划分

运行方式:
 python yolo2coco.py --root_dir ./dataset_coco --random_split
datasetcoco/images: 数据集所有图片
datasetcoco/labels: 数据集yolo标签的txt文件
classes.txt(每一行是自定义数据集中的一个类别)
"""

import os
import cv2
import json
from tqdm import tqdm
from sklearn.model_selection import train_test_split
import argparse


parser = argparse.ArgumentParser()
parser.add_argument('--root_dir', default='./data', type=str,
                    help="root path of images and labels, include ./images and ./labels and classes.txt")
parser.add_argument('--save_path', type=str, default='./train.json',
                    help="if not split the dataset, give a path to a json file")
parser.add_argument('--random_split', action='store_true', help="random split the dataset, default ratio is 8:1:1")
parser.add_argument('--split_by_file', action='store_true',
                    help="define how to split the dataset, include ./train.txt ./val.txt ./test.txt ")

arg = parser.parse_args()


def train_test_val_split_random(img_paths, ratio_train=0.8, ratio_test=0.1, ratio_val=0.1):
    # 这里可以修改数据集划分的比例。
    assert int(ratio_train + ratio_test + ratio_val) == 1
    train_img, middle_img = train_test_split(img_paths, test_size=1 - ratio_train, random_state=233)
    ratio = ratio_val / (1 - ratio_train)
    val_img, test_img = train_test_split(middle_img, test_size=ratio, random_state=233)
    print("NUMS of train:val:test = {}:{}:{}".format(len(train_img), len(val_img), len(test_img)))
    return train_img, val_img, test_img


def train_test_val_split_by_files(img_paths, root_dir):
    # 根据文件 train.txt, val.txt, test.txt(里面写的都是对应集合的图片名字) 来定义训练集、验证集和测试集
    phases = ['train', 'val', 'test']
    img_split = []
    for p in phases:
        define_path = os.path.join(root_dir, f'{p}.txt')
        print(f'Read {p} dataset definition from {define_path}')
        assert os.path.exists(define_path)
        with open(define_path, 'r') as f:
            img_paths = f.readlines()
            # img_paths = [os.path.split(img_path.strip())[1] for img_path in img_paths]  # NOTE 取消这句备注可以读取绝对地址。
            img_split.append(img_paths)
    return img_split[0], img_split[1], img_split[2]


def yolo2coco(arg):
    root_path = arg.root_dir
    print("Loading data from ", root_path)

    assert os.path.exists(root_path)
    originLabelsDir = os.path.join(root_path, 'labels')
    originImagesDir = os.path.join(root_path, 'images')
    with open(os.path.join(root_path, 'classes.txt')) as f:
        classes = f.read().strip().split()
    # images dir name
    indexes = os.listdir(originImagesDir)

    if arg.random_split or arg.split_by_file:
        # 用于保存所有数据的图片信息和标注信息
        train_dataset = {'categories': [], 'annotations': [], 'images': []}
        val_dataset = {'categories': [], 'annotations': [], 'images': []}
        test_dataset = {'categories': [], 'annotations': [], 'images': []}

        # 建立类别标签和数字id的对应关系, 类别id从0开始。
        for i, cls in enumerate(classes, 0):
            train_dataset['categories'].append({'id': i, 'name': cls, 'supercategory': 'mark'})
            val_dataset['categories'].append({'id': i, 'name': cls, 'supercategory': 'mark'})
            test_dataset['categories'].append({'id': i, 'name': cls, 'supercategory': 'mark'})

        if arg.random_split:
            print("spliting mode: random split")
            train_img, val_img, test_img = train_test_val_split_random(indexes, 0.8, 0.1, 0.1)
        elif arg.split_by_file:
            print("spliting mode: split by files")
            train_img, val_img, test_img = train_test_val_split_by_files(indexes, root_path)
    else:
        dataset = {'categories': [], 'annotations': [], 'images': []}
        for i, cls in enumerate(classes, 0):
            dataset['categories'].append({'id': i, 'name': cls, 'supercategory': 'mark'})

    # 标注的id
    ann_id_cnt = 0
    for k, index in enumerate(tqdm(indexes)):
        # 支持 png jpg 格式的图片。
        txtFile = index.replace('images', 'txt').replace('.jpg', '.txt').replace('.png', '.txt')
        # 读取图像的宽和高
        im = cv2.imread(os.path.join(root_path, 'images/') + index)
        height, width, _ = im.shape
        if arg.random_split or arg.split_by_file:
            # 切换dataset的引用对象,从而划分数据集
            if index in train_img:
                dataset = train_dataset
            elif index in val_img:
                dataset = val_dataset
            elif index in test_img:
                dataset = test_dataset
        # 添加图像的信息
        dataset['images'].append({'file_name': index,
                                  'id': k,
                                  'width': width,
                                  'height': height})
        if not os.path.exists(os.path.join(originLabelsDir, txtFile)):
            # 如没标签,跳过,只保留图片信息。
            continue
        with open(os.path.join(originLabelsDir, txtFile), 'r') as fr:
            labelList = fr.readlines()
            for label in labelList:
                label = label.strip().split()
                x = float(label[1])
                y = float(label[2])
                w = float(label[3])
                h = float(label[4])

                # convert x,y,w,h to x1,y1,x2,y2
                H, W, _ = im.shape
                x1 = (x - w / 2) * W
                y1 = (y - h / 2) * H
                x2 = (x + w / 2) * W
                y2 = (y + h / 2) * H
                # 标签序号从0开始计算, coco2017数据集标号混乱,不管它了。
                cls_id = int(label[0])
                width = max(0, x2 - x1)
                height = max(0, y2 - y1)
                dataset['annotations'].append({
                    'area': width * height,
                    'bbox': [x1, y1, width, height],
                    'category_id': cls_id,
                    'id': ann_id_cnt,
                    'image_id': k,
                    'iscrowd': 0,
                    # mask, 矩形是从左上角点按顺时针的四个顶点
                    'segmentation': [[x1, y1, x2, y1, x2, y2, x1, y2]]
                })
                ann_id_cnt += 1

    # 保存结果
    folder = os.path.join(root_path, 'annotations')
    if not os.path.exists(folder):
        os.makedirs(folder)
    if arg.random_split or arg.split_by_file:
        for phase in ['train', 'val', 'test']:
            json_name = os.path.join(root_path, 'annotations/{}.json'.format(phase))
            with open(json_name, 'w') as f:
                if phase == 'train':
                    json.dump(train_dataset, f)
                elif phase == 'val':
                    json.dump(val_dataset, f)
                elif phase == 'test':
                    json.dump(test_dataset, f)
            print('Save annotation to {}'.format(json_name))
    else:
        json_name = os.path.join(root_path, 'annotations/{}'.format(arg.save_path))
        with open(json_name, 'w') as f:
            json.dump(dataset, f)
            print('Save annotation to {}'.format(json_name))


if __name__ == "__main__":
    yolo2coco(arg)



四、xml格式转yolo数据集标签的txt格式

编写类函数,xml格式转yolo数据集标签的txt格式

代码如下(示例):

import xml.etree.ElementTree as ET

import pickle
import os
from os import listdir, getcwd
from os.path import join
import glob

classes = ["person"]


def convert(size, box):
    dw = 1.0 / size[0]
    dh = 1.0 / size[1]
    x = (box[0] + box[1]) / 2.0
    y = (box[2] + box[3]) / 2.0
    w = box[1] - box[0]
    h = box[3] - box[2]
    x = x * dw
    w = w * dw
    y = y * dh
    h = h * dh
    return (x, y, w, h)


def convert_annotation(image_name):
    in_file = open(r'C:\Users\Administrator\Desktop\person\labels\val-voc/' + image_name[:-3] + 'xml')  # xml文件路径
    out_file = open(r'C:\Users\Administrator\Desktop\person\labels\val/' + image_name[:-3] + 'txt', 'w')  # 转换后的txt文件存放路径
    f = open(r'C:\Users\Administrator\Desktop\person\labels\val-voc/' + image_name[:-3] + 'xml')
    xml_text = f.read()
    root = ET.fromstring(xml_text)
    f.close()
    size = root.find('size')
    w = int(size.find('width').text)
    h = int(size.find('height').text)

    for obj in root.iter('object'):
        cls = obj.find('name').text
        if cls not in classes:
            print(cls)
            continue
        cls_id = classes.index(cls)
        xmlbox = obj.find('bndbox')
        b = (float(xmlbox.find('xmin').text), float(xmlbox.find('xmax').text), float(xmlbox.find('ymin').text),
             float(xmlbox.find('ymax').text))
        bb = convert((w, h), b)
        out_file.write(str(cls_id) + " " + " ".join([str(a) for a in bb]) + '\n')


wd = getcwd()

if __name__ == '__main__':

    for image_path in glob.glob(r"C:\Users\Administrator\Desktop\person\images\val/*.jpg"):    # 每一张图片都对应一个xml文件这里写xml对应的图片的路径
        image_name = image_path.split('\\')[-1]
        convert_annotation(image_name)

五、根据yolo的目标检测训练的最好权重推理图片

编写类函数,根据yolo的目标检测训练的最好权重推理图片,并绘制对应的目标检测框

代码如下(示例):需要在yolov5-master文件夹下新建立一个脚本文件
path=‘./weight/fks.pt’ 训练得到的最好的权重
img_path = r’./test/V15R.jpg’ 需要检测的图片
oil_list = pd[pd[‘name’] == ‘fks’].to_numpy(),中的fks为需要检测的类别

import torch
import cv2
import matplotlib.pyplot as plt
import numpy as np

class yolo_demo:

    def __init__(self):
        # 加载目标检测模型
        self.yolo_detector = torch.hub.load('./', 'custom',
                                            path='./weight/fks.pt',
                                            source='local')

        # 设置一下置信度阈值
        self.yolo_detector.conf = 0.5

    def main(self):

        img_path = r'./test/V15R.jpg'
        img = cv2.imdecode(np.fromfile(img_path, dtype=np.uint8), -1)

        # bgr 转为 rgb
        img_rgb = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)

        # Inference
        results = self.yolo_detector(img_rgb)

        # 推理结果pd
        pd = results.pandas().xyxy[0]

        # 筛选所需要的目标类别
        oil_list = pd[pd['name'] == 'fks'].to_numpy()

        # 遍历筛选的类别, 包含坐标前四个
        for person in oil_list:

            l, t, r, b = person[:4].astype('int')
            conf, id_index, id_label = person[4:]

            # 进行绘制边界框
            cv2.rectangle(img, (l, t), (r, b), (0, 255, 0), 1)
            # cv2.putText(img, str(round(conf, 2)), (l, t-10), cv2.FONT_HERSHEY_PLAIN, 1.5, (0,255,0),1)
            #cv2.putText(img, f'{id_label} {conf:.2f}', (l, t - 10), cv2.FONT_HERSHEY_SIMPLEX, 0.9, (0, 255, 0), 1)

        cv2.imwrite('./dete.jpg', img)


plate_demo = yolo_demo()
plate_demo.main()

六、根据yolo标签的txt文件提取某一个特征类别的标签, 并在原图上进行绘制

编写类函数,根据yolo的目标检测训练的最好权重推理图片,并绘制对应的目标检测框

代码如下(示例):
image_folder = ‘./train/img’ 图片路径
label_folder = ‘./train/labels’ 标签路径
output_folder = ‘./train/output’ 输出路径

""""
根据标签的txt文件提取某一个特征类别的标签, 并在原图上进行绘制
"""
import cv2
import numpy as np
import os
import glob


# 图片和标签文件夹路径
image_folder = './train/img'
label_folder = './train/labels'
output_folder = './train/output'


# 创建输出文件夹(如果不存在)
if not os.path.exists(output_folder):
    os.makedirs(output_folder)


# 获取图片文件夹中的所有文件名
image_files = glob.glob(os.path.join(image_folder, '*.jpg'))


for image_path in image_files:

    # 获取不带后缀的文件名
    base_name = os.path.splitext(os.path.basename(image_path))[0]

    # 构造标签文件路径
    label_path = os.path.join(label_folder, base_name + '.txt')

    # 检查标签文件是否存在
    if not os.path.exists(label_path):
        print(f'Label file for {image_path} not found, skipping.')
        continue

    # 加载图片,处理中文路径
    image = cv2.imdecode(np.fromfile(image_path, dtype=np.uint8), -1)

    with open(label_path, 'r', encoding='utf-8') as file:
        lines = file.readlines()

    height, width, _ = image.shape

    # 解析标签文件并绘制边界框
    for line in lines:
        class_id, x_center, y_center, w, h = map(float, line.strip().split())

        # 仅在标签ID等于2或6时绘制
        if class_id in [0]:
            # YOLO格式中的坐标是相对于图片大小的比例,需要转换为实际像素坐标
            x_center = int(x_center * width)
            y_center = int(y_center * height)
            w = int(w * width)
            h = int(h * height)

            # 计算边界框的左上角和右下角坐标
            x1 = int(x_center - w / 2)
            y1 = int(y_center - h / 2)
            x2 = int(x_center + w / 2)
            y2 = int(y_center + h / 2)

            # 在图片上绘制矩形框
            cv2.rectangle(image, (x1, y1), (x2, y2), (0, 255, 0), 2)

    # 构造输出图片路径
    output_image_path = os.path.join(output_folder, base_name + '_labeled.jpg')

    # 保存带有标签的图片,处理中文路径
    cv2.imencode('.jpg', image)[1].tofile(output_image_path)

    print(f'Processed {os.path.basename(image_path)}, saved labeled image to {output_image_path}')

七、根据yolo标签的txt文件提取某一个特征类别的标签, 并在原图上进行绘制

# 图片和标签文件夹路径
image_folder = './train/img'
label_folder = './train/labels'
output_folder = './train/output'""""
根据标签的txt文件提取某一个特征类别的标签, 并在原图上进行绘制
"""
import cv2
import numpy as np
import os
import glob


# 图片和标签文件夹路径
image_folder = './train/img'
label_folder = './train/labels'
output_folder = './train/output'


# 创建输出文件夹(如果不存在)
if not os.path.exists(output_folder):
    os.makedirs(output_folder)


# 获取图片文件夹中的所有文件名
image_files = glob.glob(os.path.join(image_folder, '*.jpg'))


for image_path in image_files:

    # 获取不带后缀的文件名
    base_name = os.path.splitext(os.path.basename(image_path))[0]

    # 构造标签文件路径
    label_path = os.path.join(label_folder, base_name + '.txt')

    # 检查标签文件是否存在
    if not os.path.exists(label_path):
        print(f'Label file for {image_path} not found, skipping.')
        continue

    # 加载图片,处理中文路径
    image = cv2.imdecode(np.fromfile(image_path, dtype=np.uint8), -1)

    with open(label_path, 'r', encoding='utf-8') as file:
        lines = file.readlines()

    height, width, _ = image.shape

    # 解析标签文件并绘制边界框
    for line in lines:
        class_id, x_center, y_center, w, h = map(float, line.strip().split())

        # 仅在标签ID等于2或6时绘制
        if class_id in [2, 6]:
            # YOLO格式中的坐标是相对于图片大小的比例,需要转换为实际像素坐标
            x_center = int(x_center * width)
            y_center = int(y_center * height)
            w = int(w * width)
            h = int(h * height)

            # 计算边界框的左上角和右下角坐标
            x1 = int(x_center - w / 2)
            y1 = int(y_center - h / 2)
            x2 = int(x_center + w / 2)
            y2 = int(y_center + h / 2)

            # 在图片上绘制矩形框
            cv2.rectangle(image, (x1, y1), (x2, y2), (0, 255, 0), 2)

    # 构造输出图片路径
    output_image_path = os.path.join(output_folder, base_name + '_labeled.jpg')

    # 保存带有标签的图片,处理中文路径
    cv2.imencode('.jpg', image)[1].tofile(output_image_path)

    print(f'Processed {os.path.basename(image_path)}, saved labeled image to {output_image_path}')

你可能感兴趣的:(目标检测,YOLO,人工智能,计算机视觉,json)