pythons工具——裁剪labelme的json不规则多边形标签保存成矩形图像

1分钟前 264阅读

原图pythons工具——裁剪labelme的json不规则多边形标签保存成矩形图像labelme标注pythons工具——裁剪labelme的json不规则多边形标签保存成矩形图像

使用以下程序,裁剪labelme的json不规则多边形标签保存成矩形图像

import os
import cv2
import math
import json
import numpy as np
from PIL import Image, ImageDraw
def 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_y
def crop_and_rectify_polygon(image_path, json_path, output_dir=None):
    """根据JSON标注读取不规则四边形 并转换为规则矩形图像"""
    with Image.open(image_path) as img:
        img_width, img_height = img.size
        
        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:
                continue
            label = 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="./")

效果图

pythons工具——裁剪labelme的json不规则多边形标签保存成矩形图像

使用以下程序,裁剪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 warped
def 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:
            continue
        label = 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="./")

效果图

pythons工具——裁剪labelme的json不规则多边形标签保存成矩形图像

VPS购买请点击我

文章版权声明:除非注明,否则均为主机测评原创文章,转载或复制请以超链接形式并注明出处。

目录[+]