如图:
有training images:
和與之對應的ROI label:
问题:
我要如何写一个 python function去得到yolo format的bounding box 标注讯息? (bounding box是包住白点ROI的)
并所有都变成txt文件, 存在一个空文件夹里。
要得到YOLO格式的bounding box标注信息,你需要进行以下步骤:
加载图像并使用某种算法(如Canny边缘检测、阈值分割等)找到感兴趣区域(ROI)的位置。
对于每个ROI,计算它的中心坐标、宽度和高度。
将这些信息转换为YOLO格式的bounding box标注信息,并将它们保存到一个txt文件中。
下面是一个实现上述功能的Python函数示例:
import cv2
import os
def get_yolo_bbox(image_path, output_dir):
# 加载图像
img = cv2.imread(image_path)
# 对图像进行预处理,找到感兴趣区域(ROI)的位置
# 这里用Canny边缘检测作为示例
edges = cv2.Canny(img, 100, 200)
# 找到ROI的位置
contours, _ = cv2.findContours(edges, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
rois = [cv2.boundingRect(c) for c in contours]
# 转换为YOLO格式的bounding box标注信息,并保存到txt文件中
img_height, img_width, _ = img.shape
with open(os.path.join(output_dir, os.path.splitext(os.path.basename(image_path))[0] + '.txt'), 'w') as f:
for roi in rois:
x_center = (roi[0] + roi[2] / 2) / img_width
y_center = (roi[1] + roi[3] / 2) / img_height
w = roi[2] / img_width
h = roi[3] / img_height
f.write(f'0 {x_center:.6f} {y_center:.6f} {w:.6f} {h:.6f}\n')
这个函数接受一个图像文件路径和一个输出目录作为输入参数,会将YOLO格式的bounding box标注信息保存到一个txt文件中,文件名与图像文件名相同,存储在指定的输出目录下。函数使用Canny边缘检测算法作为示例找到ROI的位置,你可以根据自己的需求使用不同的算法进行ROI的检测。
使用该函数的示例代码如下:
import os
input_dir = 'path/to/input/dir'
output_dir = 'path/to/output/dir'
if not os.path.exists(output_dir):
os.makedirs(output_dir)
# 对于输入目录中的每个图像文件,生成YOLO格式的bounding box标注信息并保存到txt文件中
for filename in os.listdir(input_dir):
if filename.endswith('.jpg'):
image_path = os.path.join(input_dir, filename)
get_yolo_bbox(image_path, output_dir)
这个示例代码遍历输入目录中的每个图像文件,调用get_yolo_bbox()函数生成bounding box标注信息并将其保存到txt文件中,这些txt文件会存储到指定的输出目录下。
如果对您有帮助,请给与采纳,谢谢。
为了得到yolo格式的bounding box标注讯息,需要写一个python function,它的步骤如下:
1.获取训练图像和ROI标签。
2.读取训练图像,获取图像中ROI的位置。
3.用ROI的位置,框出ROI,生成bounding box。
4.将bounding box转换成yolo格式的annotation text file。
5.将annotation text file存入一个空文件夹中。
以下是对应的python代码:
#导入所需库文件
import cv2
import os
#1.获取训练图像和ROI标签
train_imgs_path = './train_imgs' # 训练图像路径
roi_labels_path = './roi_labels' # ROI标签路径
for img_name in os.listdir(train_imgs_path): # 遍历训练图像文件夹内的所有文件
img_path = os.path.join(train_imgs_path, img_name) # 获取当前图像的路径
img = cv2.imread(img_path) # 读取当前图像
#2.读取训练图像,获取图像中ROI的位置
roi_label_name = img_name[:-4] + '.txt' # 根据图像名字生成ROI标签名字
roi_label_path = os.path.join(roi_labels_path, roi_label_name) # 获取当前ROI标签路径
with open(roi_label_path, 'r') as f: # 打开当前标签文件
lines = f.readlines() # 读取该文件内容
for line in lines: # 遍历当前文件内容
line = line.strip().split(',') # 将字符串拆分成列表,去除多余的字符
xmin, ymin, xmax, ymax = int(line[0]), int(line[1]), int(line[2]), int(line[3]) # 获取roi位置信息
#3.用ROI的位置,框出ROI,生成bounding box
cv2.rectangle(img, (xmin, ymin), (xmax, ymax), (0, 255, 0), 1) # 框出ROI
#4.将bounding box转换成yolo格式的annotation text file
width = xmax - xmin
height = ymax - ymin
annotation = '0 {:d} {:d} {:d} {:d}'.format(xmin + width/2, ymin + height/2, width, height)
#5.将annotation text file存入一个空文件夹中
with open('yolo/' + img_name[:-4] + '.txt', 'a') as outfile: # 打开新的txt文件,用于存储annotation text file。
outfile.write(annotation + '\n') # 将annotation text file写入新的txt文件中。
cv2.imshow('img', img) # 显示框出ROI后的图片
cv2.waitKey(0) # 等待键盘触发退出
cv2.destroyAllWindows() # 销毁所有窗口
如果回答有帮助,望采纳。
为了得到yolo format的bounding box标注信息,您可以编写一个Python函数来处理每个ROI label并从中提取信息。以下是一个示例函数:
import os
def get_yolo_bounding_boxes(img_folder, label_folder, output_folder):
if not os.path.exists(output_folder):
os.makedirs(output_folder)
for label_file in os.listdir(label_folder):
# Get the corresponding image file name
img_file = os.path.join(img_folder, os.path.splitext(label_file)[0] + '.jpg')
# Open the label file and extract the ROI coordinates
with open(os.path.join(label_folder, label_file), 'r') as f:
roi_coords = f.readline().split(' ')[1:]
# Convert ROI coordinates to YOLO format
img_width, img_height = Image.open(img_file).size
x_center = float(roi_coords[0]) + float(roi_coords[2]) / 2
y_center = float(roi_coords[1]) + float(roi_coords[3]) / 2
width = float(roi_coords[2])
height = float(roi_coords[3])
x_center /= img_width
y_center /= img_height
width /= img_width
height /= img_height
# Write the bounding box coordinates to a new file in YOLO format
with open(os.path.join(output_folder, os.path.splitext(label_file)[0] + '.txt'), 'w') as f:
f.write(f"0 {x_center:.6f} {y_center:.6f} {width:.6f} {height:.6f}\n")
这个函数假定您的ROI label是一个以空格分隔的文本文件,第一行包含一个ROI的ID,后面跟着四个值,分别表示ROI的左上角x坐标、左上角y坐标、宽度和高度。函数将这些坐标值转换为YOLO格式,并将其写入一个新的文本文件中。新的文本文件的文件名应该与原始标签文件的文件名相同,只是扩展名不同。这里,我们将扩展名从.txt更改为.jpg。
为了运行这个函数,您需要将参数传递给它:
img_folder = '/path/to/training/images'
label_folder = '/path/to/ROI/labels'
output_folder = '/path/to/output/folder'
get_yolo_bounding_boxes(img_folder, label_folder, output_folder)
其中img_folder是包含训练图像的文件夹,label_folder是包含ROI标签文件的文件夹,output_folder是要将YOLO格式的标签文件存储到的文件夹。在函数执行完成后,您将在output_folder中获得与ROI标签文件相对应的YOLO格式的标签文件。
注意:这里假设所有的图片文件都是.jpg格式。如果您的图片文件是其他格式,需要适当更改代码中的图片文件扩展名。
该回答引用ChatGPT
包括读取图像、进行轮廓检测、生成 YOLO 格式标注信息、并将标注信息存储到指定的文件夹中:
import cv2
import os
def generate_yolo_annotation(img_path, roi, output_dir):
# 读取图像
img = cv2.imread(img_path)
# 获取 ROI 的坐标
x, y, w, h = cv2.boundingRect(roi)
# 计算 bounding box 的中心坐标和宽高
cx = x + w / 2
cy = y + h / 2
bw = w
bh = h
# 计算图像的宽和高
img_h, img_w, _ = img.shape
# 将坐标和尺寸归一化到 [0, 1] 范围
cx /= img_w
cy /= img_h
bw /= img_w
bh /= img_h
# 输出 YOLO 格式的标注信息
label = 0 # 0 表示 ROI
output_file = os.path.join(output_dir, os.path.splitext(os.path.basename(img_path))[0] + '.txt')
with open(output_file, 'w') as f:
f.write(f"{label} {cx:.6f} {cy:.6f} {bw:.6f} {bh:.6f}")
# 设置输入文件夹和输出文件夹
input_dir = 'path/to/input/directory'
output_dir = 'path/to/output/directory'
# 遍历输入文件夹中的所有图像文件
for filename in os.listdir(input_dir):
# 读取图像文件
img_path = os.path.join(input_dir, filename)
img = cv2.imread(img_path)
# 进行轮廓检测
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
ret, thresh = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY_INV+cv2.THRESH_OTSU)
contours, hierarchy = cv2.findContours(thresh, cv2.RETR_LIST, cv2.CHAIN_APPROX_SIMPLE)
# 生成 YOLO 格式的标注信息,并将其存储到输出文件夹中
for contour in contours:
generate_yolo_annotation(img_path, contour, output_dir)
这个代码需要将 ROI 轮廓信息作为参数传递给 generate_yolo_annotation 函数。在这个示例代码中,我们使用 OpenCV 中的 cv2.findContours 函数来进行轮廓检测,并对每个轮廓调用 generate_yolo_annotation 函数来生成标注信息。如果您有其他的方式来得到 ROI,也可以根据具体情况修改代码,将 ROI 轮廓信息传递给 generate_yolo_annotation 函数即可。
import os
import numpy as np
import cv2
def generate_yolo_annotations(images_dir, annotations_dir):
# 创建输出文件夹
os.makedirs(annotations_dir, exist_ok=True)
# 读取图像和标注
for img_filename in os.listdir(images_dir):
if img_filename.endswith('.jpg'):
# 读取图像
img_path = os.path.join(images_dir, img_filename)
img = cv2.imread(img_path)
# 读取标注文件
ann_filename = img_filename.replace('.jpg', '.txt')
ann_path = os.path.join(annotations_dir, ann_filename)
with open(ann_path, 'w') as ann_file:
# 遍历所有白点ROI并生成bounding box
# 假设标注文件格式为:每行四个数字,依次为xmin, ymin, xmax, ymax
with open(os.path.join(annotations_dir, ann_filename), 'r') as roi_file:
for line in roi_file:
roi = np.array(line.split(), dtype=int)
xmin, ymin, xmax, ymax = roi
# 计算bounding box的中心坐标和宽高
x = (xmin + xmax) / 2 / img.shape[1]
y = (ymin + ymax) / 2 / img.shape[0]
w = (xmax - xmin) / img.shape[1]
h = (ymax - ymin) / img.shape[0]
# 将bounding box的信息输出为yolo格式
ann_file.write('0 {0:.6f} {1:.6f} {2:.6f} {3:.6f}\n'.format(x, y, w, h))
def get_yolo_bounding_box(ROI):
# 获取ROI的bounding box坐标
xmin, ymin, xmax, ymax = ROI.bbox
# 计算宽度和高度
width = xmax - xmin
height = ymax - ymin
# 计算中心点的坐标
xcenter = xmin + width / 2
ycenter = ymin + height / 2
# 生成yolo格式的标注信息
yolo_label = "{} {} {} {}".format(xcenter, ycenter, width, height)
# 将标注信息写入文件
with open('yolo_label.txt', 'w') as f:
f.write(yolo_label)
# 调用函数
get_yolo_bounding_box(ROI)