该段代码的应用场景为对图像标注过后,想要对图像进行裁切,但是标签不能裁切,所以将原图像按照标签进行二值化后,将二值化后的图像进行裁切,然后使用opencv对裁切后的图像进行处理,识别出白色区域轮廓,并保存坐标信息(YOLOv8图像分割标注格式)
import os
import cv2
import numpy as np
'''
该段代码读取文件夹中的二值图像,输出白色区域的标注信息
格式为YOLOv8图像分割的txt格式
'''
def process_images(input_folder, output_folder):# 如果输出文件夹不存在,则创建它if not os.path.exists(output_folder):os.makedirs(output_folder)# 列出输入文件夹中的所有图像文件image_files = [f for f in os.listdir(input_folder) if f.endswith(('.png', '.jpg', '.jpeg', '.bmp'))]total_images = len(image_files)print(f"在文件夹'{input_folder}'中找到了 {total_images} 张图像。")# 处理每张图像for idx, filename in enumerate(image_files, 1):print(f"正在处理图像 {idx} / {total_images} : {filename}")# 加载图像image_path = os.path.join(input_folder, filename)image = cv2.imread(image_path, cv2.IMREAD_GRAYSCALE)# 检查图像是否正确加载if image is None:print(f"图像 {filename} 未能正确加载。")continue# 对图像进行阈值处理以获得二值图像_, binary_image = cv2.threshold(image, 128, 255, cv2.THRESH_BINARY)# 寻找轮廓contours, _ = cv2.findContours(binary_image, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)# 初始化一个列表来存储轮廓坐标contour_coordinates = []# 获取图像的尺寸以进行归一化height, width = image.shape# 遍历轮廓以提取归一化坐标for contour in contours:# 初始化一个列表来存储单个轮廓的坐标coords = ['0'] # 开头的数字0(没有小数点)for point in contour:# 归一化x和y坐标并添加到列表中x_normalized = point[0][0] / widthy_normalized = point[0][1] / heightcoords.extend([f"{x_normalized:.6f}", f"{y_normalized:.6f}"])# 将单个轮廓的坐标添加到主列表中contour_coordinates.append(' '.join(coords))# 定义输出文本文件的路径output_file_path = os.path.join(output_folder, os.path.splitext(filename)[0] + '.txt')# 将坐标写入文本文件with open(output_file_path, 'w') as file:file.write('\n'.join(contour_coordinates))
# 输入和输出文件夹路径(请替换为实际路径)
input_folder_path = './test_label_pre' # 替换为实际的输入文件夹路径
output_folder_path = './test_labels' # 替换为实际的输出文件夹路径# 调用函数以处理图像
process_images(input_folder_path, output_folder_path)
示例:
输入图像:
输出信息:
YOLOv8训练所需的txt标注信息: