기계는 거짓말하지 않는다

YOLO 텍스트 라벨을 이용하여 Object Crop 이미지 저장 본문

AI

YOLO 텍스트 라벨을 이용하여 Object Crop 이미지 저장

KillinTime 2024. 6. 12. 22:26

YOLO 텍스트로 된 라벨 bbox를 이용하여 object들을 crop 하여 이미지로 저장하는 코드이다.
확장자나 경로는 사용자에 맞게 바꿔야 한다.

이미지, 라벨 이름의 짝과 개수가 맞는지는 코드 실행 전 검사하여야 한다.

import cv2
import os
import glob
def get_x_y_points(point1_x, point1_y, point2_x, point2_y):
xmin, ymin, xmax, ymax = 0, 0, 0, 0
if point1_x < point2_x and point1_y < point2_y:
xmin = point1_x
ymin = point1_y
xmax = point2_x
ymax = point2_y
elif point1_x > point2_x and point1_y < point2_y:
xmin = point2_x
ymin = point1_y
xmax = point1_x
ymax = point2_y
elif point1_x < point2_x and point1_y > point2_y:
xmin = point1_x
ymin = point2_y
xmax = point2_x
ymax = point1_y
elif point1_x > point2_x and point1_y > point2_y:
xmin = point2_x
ymin = point2_y
xmax = point1_x
ymax = point1_y
return xmin, ymin, xmax, ymax
def read_yolo_label(label_path):
with open(label_path, 'r') as f:
lines = f.readlines()
labels = []
for line in lines:
parts = line.strip().split()
labels.append([int(parts[0]), float(parts[1]), float(parts[2]), float(parts[3]), float(parts[4])])
return labels
def crop_objects(image_path, label_path, output_dir):
# read image
image = cv2.imread(image_path)
h, w, _ = image.shape
# read label
labels = read_yolo_label(label_path)
for idx, label in enumerate(labels):
class_id, x_center, y_center, width, height = label
# real image scale
x_center *= w
y_center *= h
width *= w
height *= h
# calculate real image points
x_min = int(x_center - width / 2)
x_max = int(x_center + width / 2)
y_min = int(y_center - height / 2)
y_max = int(y_center + height / 2)
# arrange points
x_min, y_min, x_max, y_max = get_x_y_points(x_min, y_min, x_max, y_max)
# crop image
cropped_image = image[y_min:y_max, x_min:x_max]
image_file_name = os.path.basename(label_path)
image_file_name = os.path.splitext(image_file_name)[0]
# save
output_path = os.path.join(output_dir, f'{image_file_name}_class_{class_id}_object_{idx}.jpg')
if len(cropped_image) != 0:
cv2.imwrite(output_path, cropped_image)
# 경로 변경
source_dir_path = "./source_dir_path"
output_dir = './output_dir_path'
os.makedirs(output_dir, exist_ok=True)
# 확장자 등 변경
image_path_list = glob.glob(os.path.join(source_dir_path, "**", "*.jpg"), recursive=True)
label_path_list = glob.glob(os.path.join(source_dir_path, "**", "*.txt"), recursive=True)
for i, (image_path, label_path) in enumerate(zip(image_path_list, label_path_list)):
if ((i + 1) % 10 == 0):
print(f"{i + 1} / {len(image_path_list)}")
crop_objects(image_path, label_path, output_dir)
Comments