医疗影像ROI生成bounding box并输出成yolo格式的annotation text file

如图:

有training images:

img

和與之對應的ROI label:

img

问题:
我要如何写一个 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)

https://www.baidu.com/link?url=FaoAPGnwBjY4oov7VLXk54Gdgc0WvXVDOY_FRmU9C4kISTdF8hlnkZsJN73SEqrr7K4cqDkE9yG5GF9BkNWNp50Q9FD8itPaUBg4u2Xbivi&wd=&eqid=92f1c4ca00003bdf0000000263f2cf2a