原图labelme标注
使用以下程序,裁剪labelme的json不规则多边形标签保存成矩形图像
import os
import cv2
import math
import json
import numpy as np
from PIL import Image, ImageDrawdef calculate_bounding_box(points):"""计算多边形的最小外包矩形"""min_x = min(point[0] for point in points)min_y = min(point[1] for point in points)max_x = max(point[0] for point in points)max_y = max(point[1] for point in points)return min_x, min_y, max_x, max_ydef crop_and_rectify_polygon(image_path, json_path, output_dir=None):"""根据JSON标注读取不规则四边形 并转换为规则矩形图像"""with Image.open(image_path) as img:img_width, img_height = img.sizewith open(json_path, 'r') as f:data = json.load(f)if not output_dir:output_dir = os.path.dirname(image_path)if not os.path.exists(output_dir):os.makedirs(output_dir)for idx, shape in enumerate(data['shapes'], start=1):# 确保处理的是不规则四边形if len(shape['points']) != 4:continuelabel = shape['label']# if "ocr_" in label or "smg_" in label:if label=="车牌":# 计算不规则四边形的长边和短边长度x1, y1, x2, y2 = calculate_bounding_box(shape['points'])# 裁剪图像cropped_img = img.crop((x1, y1, x2, y2))# 保存裁剪后的图像output_filename = f"{os.path.splitext(os.path.basename(image_path))[0]}_{label}_{idx}_cropped.jpg"output_path = os.path.join(output_dir, output_filename)cropped_img.save(output_path)print(f"裁剪完成并保存至: {output_path}")if __name__ == '__main__':image_path = '1.jpg'json_path = '1.json'crop_and_rectify_polygon(image_path, json_path, output_dir="./")
效果图
使用以下程序,裁剪labelme的json不规则多边形标签保存成矩形图像
增加了放射变换
def perspective_transform(image_path, pts, output_size=(500, 500)):"""对图像中的四边形区域进行透视变换,矫正为规则矩形。:param image_path: 图像路径:param pts: 四边形的四个顶点坐标,顺序为[(top_left), (top_right), (bottom_right), (bottom_left)]:param output_size: 输出图像的尺寸,默认为(500, 500):return: 矫正后的图像"""# 读取图像img = cv2.imread(image_path)height, width = img.shape[:2]# 四边形顶点坐标调整为浮点数,并确保正确的顺序src = np.array(pts, dtype=np.float32)# 目标矩形的顶点坐标,即输出图像的四个角dst = np.array([[0, 0],[output_size[0], 0],[output_size[0], output_size[1]],[0, output_size[1]]], dtype=np.float32)# 计算透视变换矩阵M = cv2.getPerspectiveTransform(src, dst)# 执行透视变换warped = cv2.warpPerspective(img, M, output_size)return warpeddef calculate_bounding_wh(points):"""计算四边形的边长"""w1 = math.dist(points[0], points[1])h1 = math.dist(points[1], points[2])w2 = math.dist(points[2], points[3])h2 = math.dist(points[3], points[0])return int(max(w1,w2)), int(max(h1,h2))def crop_and_perspective_polygon(image_path, json_path, output_dir=None):"""根据JSON标注读取不规则四边形 并放射变换为规则矩形图像""" with open(json_path, 'r') as f:data = json.load(f)if not output_dir:output_dir = os.path.dirname(image_path)if not os.path.exists(output_dir):os.makedirs(output_dir)for idx, shape in enumerate(data['shapes'], start=1):# 确保处理的是不规则四边形if len(shape['points']) != 4:continuelabel = shape['label']# if "ocr_" in label or "smg_" in label:if label=="车牌":print(shape['points'])# 计算最小外包矩形w, h = calculate_bounding_wh(shape['points'])# 仿射变换corrected_image = perspective_transform(image_path, shape['points'], output_size=(w, h))# 保存裁剪后的图像output_filename = f"{os.path.splitext(os.path.basename(image_path))[0]}_{label}_{idx}_perspective_cropped.jpg"output_path = os.path.join(output_dir, output_filename)cv2.imwrite(output_path, corrected_image)print(f"裁剪完成并保存至: {output_path}")if __name__ == '__main__':image_path = '1.jpg'json_path = '1.json'crop_and_perspective_polygon(image_path, json_path, output_dir="./")
效果图