有关yolov5数据的各种处理方法(抽帧、拼接、亮度、json标签可视化等)

import os
import shutil
from tqdm import tqdm

import json
import cv2
import numpy as np
import re
import PIL
from PIL import Image, ImageEnhance
import os
import random



# ###清除 json内容里的 BOM 或其他隐形字符 (比如标签里存在重复的类,如两个0,或者两个1)
class JSONLabelCleaner:
    def __init__(self, directory_path):
        self.directory_path = directory_path

    def clean_label(self, label):
        # 使用正则表达式去掉所有非打印字符
        return re.sub(r'[^\x20-\x7E]', '', label)

    def process_json_file(self, file_path):
        with open(file_path, 'r', encoding='utf-8') as file:
            data = json.load(file)

        for shape in data.get('shapes', []):
            shape['label'] = self.clean_label(shape['label'])

        with open(file_path, 'w', encoding='utf-8') as file:
            json.dump(data, file, indent=2)

    def process_all_files(self):
        for json_name in os.listdir(self.directory_path):
            json_path = os.path.join(self.directory_path, json_name)
            if json_path.endswith('.json'):
                self.process_json_file(json_path)
        print('Processing complete.')

# ##图片与json标签分开
def way1():
    # 图片与json标签的同一文件夹路径
    source_folder = r'F:\Data_Yicheng\带人的垃圾数据\已标注图片\data_1500\555555\img_label'
    # 分出后用来只存放图片的路径
    out_img_folder = r'F:\Data_Yicheng\带人的垃圾数据\已标注图片\data_1500\555555\img_label/images'
    # 分出后用来只存放json标签的路径
    out_json_folder = r"F:\Data_Yicheng\带人的垃圾数据\已标注图片\data_1500\555555\img_label/label_json"

    # 确保目标文件夹存在,如果不存在则创建
    os.makedirs(out_img_folder, exist_ok=True)
    os.makedirs(out_json_folder, exist_ok=True)

    for file_name in os.listdir(source_folder):
        source_file_path = os.path.join(source_folder, file_name)
        if file_name.endswith('.jpg'):
            source_img_file_path = os.path.join(source_folder, file_name)
            destination_img_file_path = os.path.join(out_img_folder, file_name)
            shutil.move(source_img_file_path, destination_img_file_path)

        elif file_name.endswith('.json'):
            source_json_file_path = os.path.join(source_folder, file_name)
            destination_json_file_path = os.path.join(out_json_folder, file_name)
            shutil.move(source_json_file_path, destination_json_file_path)
    print("=======ok")


# ## 找出没有标签得图片
def way2():
    # 定义文件夹路径
    image_folder = r"F:\Data_Yicheng\带人的垃圾数据\已标注图片\data_1500\555555\img_label\images"
    json_folder = r"F:\Data_Yicheng\带人的垃圾数据\已标注图片\data_1500\555555\img_label\label_json"

    # 获取文件夹1中的所有图片文件名(假设图片文件扩展名为.jpg或.png)
    image_files = [f for f in os.listdir(image_folder) if f.endswith(('.jpg', '.png'))]

    # 获取文件夹2中的所有JSON文件名
    json_files = [f for f in os.listdir(json_folder) if f.endswith('.json')]

    # 从JSON文件名中去掉扩展名
    json_files_without_ext = [os.path.splitext(f)[0] for f in json_files]

    # 找出文件夹1中没有在文件夹2中对应的图片文件
    images_without_json = [f for f in image_files if os.path.splitext(f)[0] not in json_files_without_ext]

    print("没有对应JSON标签的图片文件:")
    for image in images_without_json:
        print(image)
        image_path = os.path.join(image_folder, image)
        os.remove(image_path)
        print()
        print(f"已删除:{image}")


# 划分数据集 (这里划分的数据集由于用的是json格式因此划分完还是json格式)
def way3():

    """ 使用:只需要修改 1. Dataset_folde,
                      2. os.chdir(os.path.join(Dataset_folder, 'images'))里的 images,
                      3. val_scal = 0.2
                      4. os.chdir('../label_json')          label_json换成自己json标签文件夹名称   """

    # 图片文件夹与json标签文件夹的根目录
    Dataset_folder = r'F:\Data_Yicheng\带人的垃圾数据\已标注图片\data_1500'

    # 把当前工作目录改为指定路径
    os.chdir(os.path.join(Dataset_folder, 'images'))  # images : 图片文件夹的名称
    folder = '.'  # 代表os.chdir(os.path.join(Dataset_folder, 'images'))这个路径
    imgs_list = os.listdir(folder)

    random.seed(123)  # 固定随机种子,防止运行时出现bug后再次运行导致imgs_list 里面的图片名称顺序不一致

    random.shuffle(imgs_list)  # 打乱

    val_scal = 0.2  # 验证集比列
    val_number = int(len(imgs_list) * val_scal)
    val_files = imgs_list[:val_number]
    train_files = imgs_list[val_number:]

    print('all_files:', len(imgs_list))
    print('train_files:', len(train_files))
    print('val_files:', len(val_files))

    os.mkdir('train')
    for each in tqdm(train_files):
        shutil.move(each, 'train')

    os.mkdir('val')
    for each in tqdm(val_files):
        shutil.move(each, 'val')

    os.chdir('../label_json')

    os.mkdir('train')
    for each in tqdm(train_files):
        json_file = os.path.splitext(each)[0] + '.json'
        shutil.move(json_file, 'train')

    os.mkdir('val')
    for each in tqdm(val_files):
        json_file = os.path.splitext(each)[0] + '.json'
        shutil.move(json_file, 'val')

    print('划分完成')


# ##把json标签转------yolo8------的txt格式 (这里是经过way3划分好数据集的再用这里代码转换)
def way4():

    """使用: 1.修改类别 classes     你是几个类别就添加,比如你是类别cat,dog 则修改成classes = {'cat':0, 'dog':1}
             2.修改 Dataset_root 成自己路径
             3.修改os.chdir('json_label/train') 与 os.chdir('json_label/val ') ---> 标签文件夹下的train与val文件夹路径                        """

    # 图片与标签json文件的路径(Dataset_root下是图片文件夹与json标签文件夹)
    Dataset_root = r'F:\Data_Yicheng\带人的垃圾数据\已标注图片\data_1500\555555\img_label'

    classes = {
        '0': 0,
        '1人': 1,
        '2手': 2

    }

    os.chdir(Dataset_root)

    os.mkdir('labels')
    os.mkdir('labels/train')
    os.mkdir('labels/val')

    def process_single_json(labelme_path, save_folder='../../labels/train'):
        # 载入 labelme格式的 json 标注文件
        with open(labelme_path, 'r', encoding='utf-8') as f:
            labelme = json.load(f)

        img_width = labelme['imageWidth']  # 图像宽度
        img_height = labelme['imageHeight']  # 图像高度

        # 生成 YOLO 格式的 txt 文件
        suffix = labelme_path.split('.')[-2]
        yolo_txt_path = suffix + '.txt'

        with open(yolo_txt_path, 'w', encoding='utf-8') as f:
            for each_ann in labelme['shapes']:  # 遍历每个框

                if each_ann['shape_type'] == 'rectangle':  # 筛选出框

                    # 获取类别 ID
                    bbox_class_id = classes[each_ann['label']]

                    # 左上角和右下角的 XY 像素坐标
                    bbox_top_left_x = int(min(each_ann['points'][0][0], each_ann['points'][1][0]))
                    bbox_bottom_right_x = int(max(each_ann['points'][0][0], each_ann['points'][1][0]))
                    bbox_top_left_y = int(min(each_ann['points'][0][1], each_ann['points'][1][1]))
                    bbox_bottom_right_y = int(max(each_ann['points'][0][1], each_ann['points'][1][1]))

                    # 框中心点的 XY 像素坐标
                    bbox_center_x = int((bbox_top_left_x + bbox_bottom_right_x) / 2)
                    bbox_center_y = int((bbox_top_left_y + bbox_bottom_right_y) / 2)

                    # 框宽度
                    bbox_width = bbox_bottom_right_x - bbox_top_left_x

                    # 框高度
                    bbox_height = bbox_bottom_right_y - bbox_top_left_y

                    # 框中心点归一化坐标
                    bbox_center_x_norm = bbox_center_x / img_width
                    bbox_center_y_norm = bbox_center_y / img_height

                    # 框归一化宽度
                    bbox_width_norm = bbox_width / img_width
                    # 框归一化高度
                    bbox_height_norm = bbox_height / img_height

                    # 生成 YOLO 格式的一行标注,指定保留小数点后几位
                    bbox_yolo_str = '{} {:.4f} {:.4f} {:.4f} {:.4f}'.format(bbox_class_id, bbox_center_x_norm,
                                                                            bbox_center_y_norm, bbox_width_norm,
                                                                            bbox_height_norm)
                    # 写入 txt 文件中
                    f.write(bbox_yolo_str + '\n')

        shutil.move(yolo_txt_path, save_folder)
        print('{} --> {} 转换完成'.format(labelme_path, yolo_txt_path))

    os.chdir('label_json/train')  # 标签文件夹下的train文件夹路径
    save_folder = '../../labels/train'
    for labelme_path in os.listdir():
        process_single_json(labelme_path, save_folder=save_folder)
    print('YOLO格式的txt标注文件已保存至 ', save_folder)

    os.chdir(Dataset_root)

    os.chdir('label_json/val')  # 标签文件夹下的val文件夹路径
    save_folder = '../../labels/val'
    for labelme_path in os.listdir():
        process_single_json(labelme_path, save_folder=save_folder)
    print('YOLO格式的txt标注文件已保存至 ', save_folder)



# ##把json标签转-----yolo5-----的txt格式 (没划分数据集)
def way5(jsons_label_path, txt_save_folder):

    """使用: 1.修改类别 classes     你是几个类别就添加,比如你是类别cat,dog 则修改成classes = {'cat':0, 'dog':1}   """

    # 图片与标签json文件的路径(Dataset_root下是图片文件夹与json标签文件夹), 左边是json里的类别,右边是准备转换成yolo的类别
    classes = {
        '0': 0,
        '1': 1,
        '2': 2

    }

    def process_single_json(labelme_path, save_folder):
        # 载入 labelme格式的 json 标注文件
        with open(labelme_path, 'r', encoding='utf-8') as f:
            labelme = json.load(f)

        # 生成 YOLO 格式的 txt 文件
        suffix = os.path.basename(labelme_path)
        prefix, _ = os.path.splitext(suffix)
        yolo_txt_path = os.path.join(save_folder, prefix + '.txt')
        with open(yolo_txt_path, 'w', encoding='utf-8') as f:
            if labelme == {}:
                print(f"生成了一个空txt : {yolo_txt_path}")
            else:
                img_width = labelme['imageWidth']  # 图像宽度
                img_height = labelme['imageHeight']  # 图像高度
                for each_ann in labelme['shapes']:  # 遍历每个框

                    if each_ann['shape_type'] == 'rectangle':  # 筛选出框

                        # 获取类别 ID
                        bbox_class_id = classes[each_ann['label']]

                        # 左上角和右下角的 XY 像素坐标
                        bbox_top_left_x = int(min(each_ann['points'][0][0], each_ann['points'][1][0]))
                        bbox_bottom_right_x = int(max(each_ann['points'][0][0], each_ann['points'][1][0]))
                        bbox_top_left_y = int(min(each_ann['points'][0][1], each_ann['points'][1][1]))
                        bbox_bottom_right_y = int(max(each_ann['points'][0][1], each_ann['points'][1][1]))

                        # 框中心点的 XY 像素坐标
                        bbox_center_x = int((bbox_top_left_x + bbox_bottom_right_x) / 2)
                        bbox_center_y = int((bbox_top_left_y + bbox_bottom_right_y) / 2)

                        # 框宽度
                        bbox_width = bbox_bottom_right_x - bbox_top_left_x

                        # 框高度
                        bbox_height = bbox_bottom_right_y - bbox_top_left_y

                        # 框中心点归一化坐标
                        bbox_center_x_norm = bbox_center_x / img_width
                        bbox_center_y_norm = bbox_center_y / img_height

                        # 框归一化宽度
                        bbox_width_norm = bbox_width / img_width
                        # 框归一化高度
                        bbox_height_norm = bbox_height / img_height

                        # 生成 YOLO 格式的一行标注,指定保留小数点后几位
                        bbox_yolo_str = '{} {:.4f} {:.4f} {:.4f} {:.4f}'.format(bbox_class_id, bbox_center_x_norm,
                                                                                bbox_center_y_norm, bbox_width_norm,
                                                                                bbox_height_norm)
                        # 写入 txt 文件中
                        f.write(bbox_yolo_str + '\n')

                print('{} --> {} 转换完成'.format(labelme_path, yolo_txt_path))

    jsons_label_path = jsons_label_path
    save_folder = txt_save_folder
    os.makedirs(save_folder, exist_ok=True)
    for js_name in os.listdir(jsons_label_path):
        if js_name.endswith('.json'):
            js_label_path = os.path.join(jsons_label_path, js_name)
            process_single_json(js_label_path, save_folder=save_folder)

    print('YOLO5格式的txt标注文件已保存至 ', save_folder)


# ## json标签对应图片的可视化
def way6():

    images_path = r'F:\Data_Yicheng\带人的垃圾数据\已标注图片\data_1500\555555\img_label\images'
    json_path = r'F:\Data_Yicheng\带人的垃圾数据\已标注图片\data_1500\555555\img_label\label_json'
    out_path = r'F:\Data_Yicheng\带人的垃圾数据\已标注图片\data_1500\555555\img_label\out'
    num = 0
    for name in os.listdir(images_path):
        if name.lower().endswith(('.jpg', '.png', '.jpeg')):  # lower()把字符串中有大写的部分改成小写
            try:
                prefix, suffix = os.path.splitext(name)
                file_json_name = f"{prefix}.json"
                img_path = os.path.join(images_path, name)
                file_json_path = os.path.join(json_path, file_json_name)

                # 载入图像
                img_path = img_path
                img_bgr = cv2.imread(img_path)

                # 可视化
                # plt.imshow(img_bgr[:,:,::-1]) # 将bgr通道转换成rgb通道
                # plt.show()

                # 载入labelme格式的json标注文件
                labelme_path = file_json_path

                with open(labelme_path, 'r', encoding='utf-8') as f:
                    labelme = json.load(f)

                # 查看标注信息  rectangle:矩形  point:点  polygon:多边形
                # print(labelme.keys())
                # dict_keys(['version', 'flags', 'shapes', 'imagePath', 'imageData', 'imageHeight', 'imageWidth'])
                # print(labelme['shapes'])

                # <<<<<<<<<<<<<<<<<<可视化框(rectangle)标注>>>>>>>>>>>>>>>>>>>>>
                # 框可视化配置
                bbox_color = (255, 129, 0)  # 框的颜色
                bbox_thickness = 5  # 框的线宽

                # 框类别文字
                bbox_labelstr = {
                    'font_size': 1,  # 字体大小
                    'font_thickness': 2,  # 字体粗细
                    'offset_x': 0,  # X 方向,文字偏移距离,向右为正
                    'offset_y': -8,  # Y 方向,文字偏移距离,向下为正
                }
                # 画框
                for each_ann in labelme['shapes']:  # 遍历每一个标注

                    if each_ann['shape_type'] == 'rectangle':  # 筛选出框标注

                        # 框的类别
                        bbox_label = each_ann['label']
                        # 框的两点坐标
                        bbox_keypoints = each_ann['points']
                        bbox_keypoint_A_xy = bbox_keypoints[0]
                        bbox_keypoint_B_xy = bbox_keypoints[1]
                        # 左上角坐标
                        bbox_top_left_x = int(min(bbox_keypoint_A_xy[0], bbox_keypoint_B_xy[0]))
                        bbox_top_left_y = int(min(bbox_keypoint_A_xy[1], bbox_keypoint_B_xy[1]))
                        # 右下角坐标
                        bbox_bottom_right_x = int(max(bbox_keypoint_A_xy[0], bbox_keypoint_B_xy[0]))
                        bbox_bottom_right_y = int(max(bbox_keypoint_A_xy[1], bbox_keypoint_B_xy[1]))

                        # 画矩形:画框
                        img_bgr = cv2.rectangle(img_bgr, (bbox_top_left_x, bbox_top_left_y),
                                                (bbox_bottom_right_x, bbox_bottom_right_y),
                                                bbox_color, bbox_thickness)

                        bbox_label = f"cls: {bbox_label}"
                        # 写框类别文字:图片,文字字符串,文字左上角坐标,字体,字体大小,颜色,字体粗细
                        img_bgr = cv2.putText(img_bgr, bbox_label, (
                            bbox_top_left_x,
                            bbox_top_left_y - 10),
                                              cv2.FONT_HERSHEY_SIMPLEX, bbox_labelstr['font_size'], (0, 0, 255),
                                              bbox_labelstr['font_thickness'])

                # # 可视化
                # plt.imshow(img_bgr[:,:,::-1]) # 将bgr通道转换成rgb通道
                # plt.show()

                # 可视化
                # plt.imshow(img_bgr[:, :, ::-1])  # 将bgr通道转换成rgb通道,因为plt要求的正常顺序是rgb
                # plt.show()

                # 当前目录下保存可视化结果
                cv2.imwrite(f'{out_path}\\{name}', img_bgr)

            except Exception as e:
                print(e)


# ### 把所有的图片与图片对应的json标里那些存在图片没有对应的json标签  存在json标签又没有对应的图片的情况都找出来并删除
def way7(dir_path):
    # Set your directory path
    directory = dir_path
    # Get lists of all images and JSON files
    image_files = set()
    json_files = set()

    # Populate lists with image and JSON file names (without extensions)
    for file in os.listdir(directory):
        if file.endswith('.jpg') or file.endswith('.png'):
            image_files.add(os.path.splitext(file)[0])
        elif file.endswith('.json'):
            json_files.add(os.path.splitext(file)[0])

    # Identify unmatched files

    images_without_json = image_files - json_files   # image_files 里的图片在json_files 里没有对应的json文件 的有哪些
    jsons_without_image = json_files - image_files   # json_files  里的json文件在image_files里没有对应的图片 的有哪些

    print(images_without_json)
    print(jsons_without_image)
    exit()

    # Delete unmatched files
    for image in images_without_json:
        image_path = os.path.join(directory, image + '.jpg')
        if os.path.exists(image_path):
            os.remove(image_path)
        else:
            image_path = os.path.join(directory, image + '.png')
            if os.path.exists(image_path):
                os.remove(image_path)

    for json_file in jsons_without_image:
        json_path = os.path.join(directory, json_file + '.json')
        if os.path.exists(json_path):
            os.remove(json_path)

    print(f'Deleted {len(images_without_json)} images without corresponding JSON files.')
    print(f'Deleted {len(jsons_without_image)} JSON files without corresponding images.')


# ## 在所有的图片与图片对应的json标签文件夹里,找出没有对应的json标签的图片并且给没有json标签对应的图片生成一个对应的json文件(内容是空的就行) 然后打印出没有图片对应的json标签
def way8(dir_path):
    # 目录路径
    directory = dir_path

    # 获取目录下所有文件
    files = os.listdir(directory)

    # 分别存储图片和JSON文件的集合
    image_files = set()
    json_files = set()

    # 分类文件
    for file in files:
        if file.endswith('.jpg') or file.endswith('.png'):  # 根据实际图片格式调整
            image_files.add(os.path.splitext(file)[0])
        elif file.endswith('.json'):
            json_files.add(os.path.splitext(file)[0])

    # 找出没有对应JSON文件的图片
    missing_json_files = image_files - json_files
    print("找出没有对应JSON文件的图片:", missing_json_files)

    # 为没有对应JSON文件的图片生成空的JSON文件,并打印文件名称
    for image in missing_json_files:
        empty_json_path = os.path.join(directory, image + '.json')
        with open(empty_json_path, 'w') as f:
            json.dump({}, f)
        print(f'Generated empty JSON file: {empty_json_path}')

    # 找出没有对应图片的JSON文件
    missing_image_files = json_files - image_files

    # 打印没有对应图片的JSON文件名称
    for json_file in missing_image_files:
        print(f'Missing image for JSON file: {os.path.join(directory, json_file + ".json")}')


###  ============== 把猫咪贴在原图得左右上角得300x300得范围 ========================
def cat_past_in_source_img():
    # 路径1和路径2
    path1 = r"F:\Data_Yicheng\Cat_dog\imgs"
    path2 = r"F:\Data_Yicheng\8888888888888"
    output_path = r"F:\Data_Yicheng\output_images"  # 输出目录

    # 创建输出目录
    os.makedirs(output_path, exist_ok=True)

    # 获取路径1和路径2的所有图片文件
    cat_images = [os.path.join(path1, img) for img in os.listdir(path1) if img.endswith(('png', 'jpg', 'jpeg'))]
    dataset_images = [os.path.join(path2, img) for img in os.listdir(path2) if img.endswith(('png', 'jpg', 'jpeg'))]
    num = 0
    for dataset_img_path in dataset_images:
        dataset_img = Image.open(dataset_img_path).convert("RGBA")
        width, height = dataset_img.size

        if width < 600 or height < 300:
            print(f"Image {dataset_img_path} is too small to place two 300x300 boxes.")
            continue

        # 随机选择两张猫咪图片
        cat_img1_path, cat_img2_path = random.sample(cat_images, 2)
        cat_img1 = Image.open(cat_img1_path).convert("RGBA")
        cat_img2 = Image.open(cat_img2_path).convert("RGBA")

        # 如果猫咪图片的尺寸超过300x300,则缩放到300x300以内
        if cat_img1.size[0] > 300 or cat_img1.size[1] > 300:
            cat_img1.thumbnail((300, 300))
        if cat_img2.size[0] > 300 or cat_img2.size[1] > 300:
            cat_img2.thumbnail((300, 300))

        # 获取猫咪图片的尺寸
        cat_img1_width, cat_img1_height = cat_img1.size
        cat_img2_width, cat_img2_height = cat_img2.size

        # 随机生成左上角300x300框内的粘贴位置
        x1 = random.randint(0, 300 - cat_img1_width)
        y1 = random.randint(0, 300 - cat_img1_height)

        # 随机生成右上角300x300框内的粘贴位置
        x2 = random.randint(width - 300, width - cat_img2_width)
        y2 = random.randint(0, 300 - cat_img2_height)

        # 将猫咪图片粘贴到数据集图片的随机位置
        dataset_img.paste(cat_img1, (x1, y1), cat_img1)
        dataset_img.paste(cat_img2, (x2, y2), cat_img2)

        # 保存处理后的图片
        output_img_path = os.path.join(output_path, os.path.basename(dataset_img_path))
        dataset_img.convert("RGB").save(output_img_path)
        print(f"Processed and saved image: {output_img_path}")
        num += 1

##  随机调整图片亮度
def process_images_in_folder(folder_path):
    """
    遍历文件夹中的所有图片文件,调整亮度并保存
    :param folder_path: 包含图片的文件夹路径
    """
    # 遍历文件夹中的所有文件
    for filename in os.listdir(folder_path):
        if filename.lower().endswith(('.png', '.jpg', '.jpeg', '.bmp', '.gif')):
            # 构造图片的完整路径
            img_path = os.path.join(folder_path, filename)
            # 打开图片
            with Image.open(img_path) as img:
                # 生成一个随机的亮度调整因子
                brightness_factor = random.uniform(0.8, 1.6)
                # 调整亮度
                enhancer = ImageEnhance.Brightness(img)
                bright_img = enhancer.enhance(brightness_factor)
                new_filename = f"adjusted88_{brightness_factor:.2f}_{filename}"
                new_img_path = os.path.join(folder_path, new_filename)
                # 保存修改后的图片
                bright_img.save(new_img_path)
                print(f"Processed {filename} to {new_img_path}")



##   图片拼接
def picture_stitching():
    # 定义路径
    source_dir = "F:\\8888\\5"  # 图1路径
    random_image_dir = "F:\\8888"  # 图2路径
    output_dir = "F:\\8888\\out2"  # 拼图完成的保存路径

    # 确保输出目录存在
    os.makedirs(output_dir, exist_ok=True)

    # 获取所有图片文件
    source_images = [os.path.join(source_dir, f) for f in os.listdir(source_dir) if
                     f.endswith(('.png', '.jpg', '.jpeg'))]
    random_images = [os.path.join(random_image_dir, f) for f in os.listdir(random_image_dir) if
                     f.endswith(('.png', '.jpg', '.jpeg'))]

    for source_image_path in source_images:
        # 打开源图像
        source_image = Image.open(source_image_path)

        # 随机选择一张图片
        random_image_path = random.choice(random_images)
        random_image = Image.open(random_image_path)

        # 调整随机图片大小以匹配源图像
        random_image = random_image.resize(source_image.size)

        # 拼接图片
        combined_image = Image.new('RGB', (source_image.width * 2, source_image.height))
        combined_image.paste(source_image, (0, 0))
        combined_image.paste(random_image, (source_image.width, 0))

        # 保存拼接后的图片
        output_image_path = os.path.join(output_dir, os.path.basename(source_image_path))
        combined_image.save(output_image_path)

    print("图片拼接完成。")


##  视频抽帧
def way_9(v_path=r'F:\Data_Yicheng\网球怕测试视频',
           out_path=r'F:\Data_Yicheng\网球怕测试视频\3_images'):
    if not os.path.exists(out_path):
        os.makedirs(out_path)

    for root, dirs, files in os.walk(v_path):     # files 得到是路径v_path 下的所有视频文件

        for i, file in enumerate(files):
            if file.endswith(('.mp4', '.avi', '.mov', '.mkv')):

                video_path = os.path.join(v_path, file)

                cap = cv2.VideoCapture(video_path)
                frame_count = 0
                image_count = 0
                while cap.isOpened():
                    ret, frame = cap.read()
                    if not ret:
                        break

                    # 每5帧抽一张
                    if frame_count % 3 == 0:
                        image_path = os.path.join(out_path, f"819{i}_{frame_count}.jpg")
                        cv2.imwrite(image_path, frame)
                        image_count += 1
                    frame_count += 1
                cap.release()
                print(f"处理了 {image_count} 张图片 from  {file}")

###   统计总框数
def count_box_num(folder_path):
    # 指定 JSON 文件所在的路径
    folder_path = folder_path

    # 初始化计数器
    empty_content = {}
    file_rect_count = {}  # 每个文件的矩形框数量
    total_rect_count = 0  # 所有文件的矩形框总数量

    # 遍历路径下的所有文件
    for filename in os.listdir(folder_path):
        if filename.endswith(".json"):
            file_path = os.path.join(folder_path, filename)
            with open(file_path, 'r', encoding='utf-8') as file:
                try:
                    data = json.load(file)
                    # 如果json文件是空的({}),跳过
                    if not data:
                        empty_content[filename] = "空内容"
                        # print(filename, "是空")
                        file_rect_count[filename] = 0
                        continue

                    shapes = data.get("shapes", [])
                    rect_count = len(shapes)
                    file_rect_count[filename] = rect_count
                    total_rect_count += rect_count
                except json.JSONDecodeError:
                    print(f"文件 {filename} 解析失败,可能不是有效的 JSON 文件。")
                    continue

    print("空内容的标签", empty_content)
    print()
    # 打印每个文件的矩形框数量
    print(file_rect_count)
    print()

    # 打印所有文件的矩形框总数量
    print(f"所有文件中的矩形框总数量: {total_rect_count}")



###  图片转rgb 转jpg
def to_rgb_jpg():
    folder_path = r'F:\Data_Yicheng\Cat_dog\999'
    num = 0
    for im in os.listdir(folder_path):

        prefix = os.path.splitext(im)[1]
        if prefix not in ['.jpg']:

            im_path = os.path.join(folder_path, im)
            img = Image.open(im_path)
            if img.mode != "RGB":
                img = img.convert("RGB")
            img.save(f"{folder_path}/24898q{num}c.jpg")
            num += 1

    print("copletect")




if __name__ == '__main__':
    # ###清除 json内容里的 BOM 或其他隐形字符 (比如标签里存在重复的类,如两个0,把两个0合并成1个,或者两个1,把两个1合并成1个),再比如带中文的字符,比如(“1人”-- 变成1,    “2手”-- 变成2)
    # j = JSONLabelCleaner(directory_path=r'F:\Data_Yicheng\已标注垃圾\标注\图片与标签\第二版50个视频抽帧的图片3771\第二版50个视频抽帧的图片3771')
    # j.process_all_files()

    # ## 注意:::(要改函数里的标签对应)         把json标签转-----yolo5-----的txt格式 (没划分数据集)
    # way5(jsons_label_path=r'F:\Data_Yicheng\已标注垃圾\标注\图片与标签\第二版50个视频抽帧的图片3771\第二版50个视频抽帧的图片3771', txt_save_folder=r'F:\Data_Yicheng\已标注垃圾\标注\图片与标签\第二版50个视频抽帧的图片3771\labels')

    # ###  把所有的图片与图片对应的json标里那些存在图片没有对应的json标签  存在json标签又没有对应的图片的情况都找出来并删除
    # way7(dir_path=r'F:\Data_Yicheng\all_garbige_data\v5_all_images_labels\all_images_labels')


    # ## 在所有的图片与图片对应的json标签文件夹里,找出没有对应的json标签的图片并且给没有json标签对应的图片生成一个对应的json文件(内容是空的就行) 然后打印出没有图片对应的json标签
    # way8(dir_path=r'F:\Data_Yicheng\已标注垃圾\标注\图片与标签\第二版50个视频抽帧的图片3771\第二版50个视频抽帧的图片3771')

    ###  图片转rgb 转jpg
    # to_rgb_jpg()

    # ###   统计总框数            # 指定 JSON 文件所在的路径
    # count_box_num(folder_path=r"F:\Data_Yicheng\已标注垃圾\标注\图片与标签\第二版50个视频抽帧的图片3771\第二版50个视频抽帧的图片3771")

    # way_9()

















评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值