0
点赞
收藏
分享

微信扫一扫

将 10 亿条日志行从 OpenSearch 迁移到 Elasticsearch

Python OpenCV剪裁图片并修改对应的Labelme标注文件

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

前言

前提条件

相关介绍

实验环境

剪裁图片并修改对应的Labelme标注文件

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

代码实现

import os
import cv2
import json
import numpy as np

def xyxy2xywh(rect):
    '''
    (x1,y1,x2,y2) -> (x,y,w,h)
    '''
    return [rect[0],rect[1],rect[2]-rect[0],rect[3]-rect[1]]

def xywh2xyxy(rect):
    '''
    (x,y,w,h) -> (x1,y1,x2,y2)
    '''
    return [rect[0],rect[1],rect[0]+rect[2],rect[1]+rect[3]]

def xyxy2xminyminxmaxymax(rect):
    xmin = min(rect[0],rect[2])
    ymin = min(rect[1],rect[3])
    xmax = max(rect[0],rect[2])
    ymax = max(rect[1],rect[3])
    return [xmin,ymin,xmax,ymax]

def alter_json(img_name,in_json_path,out_json_path,crop_x,crop_y,crop_height,crop_width,pad):
    '''
    in_json_path: json文件输入路径
    out_json_path: json文件保存路径
    crop_x : 剪裁矩阵坐标的x
    crop_y : 剪裁矩阵坐标的y
    crop_height: 剪裁后的高
    crop_width: 剪裁后的宽
    pad: 图片填充数
    '''
    file_in = open(in_json_path, "r", encoding='utf-8')
    # json.load数据到变量json_data
    json_data = json.load(file_in)
    # 修改json中的内容
    json_data["imageHeight"] = crop_height
    json_data["imageWidth"] = crop_width + 2*pad
    json_data["imagePath"] = img_name
    json_data["imageData"] = None
    # 读取原始jsons的 [[x1,y1],[x2,y2]]
    for LabelBox in json_data['shapes']:
        points = LabelBox['points']
        points[0][0] = points[0][0] - crop_x + pad
        points[0][1] =points[0][1] - crop_y 
        points[1][0] = points[1][0] - crop_x + pad
        points[1][1] = points[1][1] - crop_y 
    file_in.close()

    # 创建一个写文件
    file_out = open(out_json_path, "w", encoding='utf-8')
    # 将修改后的数据写入文件
    file_out.write(json.dumps(json_data))
    file_out.close()

# 图像显示函数
def show(name, img):
    cv2.namedWindow(name, 0)  # 用来创建指定名称的窗口,0表示CV_WINDOW_NORMAL
    # cv2.resizeWindow(name, img.shape[1], img.shape[0]); # 设置宽高大小为640*480
    cv2.imshow(name, img)
    cv2.waitKey(0)
    cv2.destroyAllWindows()

def crop_largest_img(image):
    '''
    参数:
        image 是彩色图像数组。
    '''
    # 转换为灰度图像
    gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)

    # 二值化
    _, binary = cv2.threshold(gray, 50, 255, cv2.THRESH_BINARY)
    # show('binary',binary)

    # 查找轮廓
    contours, hierarchy = cv2.findContours(binary,cv2.RETR_LIST,cv2.CHAIN_APPROX_SIMPLE)
    '''
    retval = cv2.boundingRect( cnt )

    参数:
        cnt 是灰度图像或轮廓。
    返回值:
        retval 表示返回的矩形边界的左上角顶点的坐标值及矩形边界的宽度和高度,即x,y,w,h
    '''
    for cnt in contours:
        x,y,w,h = cv2.boundingRect(cnt) # 获取轮廓顶点及边长
        if w*h<600*600: # 过滤掉小于600*600的矩形框
            continue
        # print(x,y,w,h) # 570 126 1039 728 左上角x 左上角y 框宽 框高
        # cv2.rectangle(image,(x,y),(x+w,y+h),(255,0,0),10) # xmin,ymin,xmax,ymax
    # show('image',image)
    return x,y,w,h


if __name__=="__main__":
    # 输出图片所在文件夹
    out_imgs_dir  = 'out_images/'
    # 输出jsons所在文件夹
    out_jsons_dir = 'out_jsons/'
    if not os.path.exists(out_imgs_dir):
        os.mkdir(out_imgs_dir)
    if not os.path.exists(out_jsons_dir):
        os.mkdir(out_jsons_dir)

    # 输入图片所在文件夹
    in_imgs_dir  = 'images/'
    # 输入jsons所在文件夹
    in_jsons_dir = 'jsons/'
    # 输入图片名列表
    file_name_list = os.listdir(in_imgs_dir)
    img_name_list = [i for i in file_name_list if i.endswith('.png')]
    # 输入jsons文件名列表
    file_name_list = os.listdir(in_jsons_dir)
    json_name_list = [i for i in file_name_list if i.endswith('.json')]
    # print(img_name_list,json_name_list)

    # 定义剪裁图片的左右填充数
    pad = 0

    for img_name,json_name in zip(img_name_list,json_name_list):
        in_img_path = os.path.join(in_imgs_dir,img_name)
        out_img_path = os.path.join(out_imgs_dir,img_name)
        in_json_path = os.path.join(in_jsons_dir,json_name)
        out_jsons_path = os.path.join(out_jsons_dir,json_name)
        # print(in_img_path,in_json_path)
        # 读取图片
        image = cv2.imread(in_img_path)
        # 获得最大剪裁矩形坐标(x,y,w,h)
        x,y,w,h = crop_largest_img(image)
        # print(x,y,w,h)
        # 读取并修改json文件
        alter_json(img_name,in_json_path,out_jsons_path,x,y,h,w,pad=pad)
        # 保存剪裁图片
        crop_img = image[y:y+h,x-pad:x+w+pad] # h,w

        cv2.imwrite(out_img_path,crop_img)

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

举报

相关推荐

0 条评论