OpenCV使用切片方式裁剪目标区域并保存

目录

需求:

分析:

代码实现:

注意事项:


需求:

从标注的数据(一个Images文件,以及对应Annotations文件)中裁剪出目标区域,并将目标区域图片保存在同一个文件夹里。

分析:

1、图片名称和对应的xml文件名称相同。

2、一张X光片上不止一个地方有骨折

3、思路:获取图片的路径,用CV读取图片,因为图片名和xml名称前缀一样,可以同时读取xml文件,使用xml.etree.ElementTree解析xml文件获取目标区域的xmin,ymin,xmax,ymax坐标

OpenCV使用切片方式裁剪目标区域并保存_第1张图片

OpenCV使用切片方式裁剪目标区域并保存_第2张图片

 代码实现:

import os
import xml.etree.ElementTree as ET
import cv2
from tqdm import tqdm

#解析xml文件获得bbox坐标
def get_bbox(xml_path):
    bbox_list = []
    tree =ET.parse(xml_path)
    for obj in tree.iter("object"):
        xmin  = obj.findtext("./bndbox/xmin")
        ymin = obj.findtext("./bndbox/ymin")
        xman = obj.findtext("./bndbox/xmax")
        ymax = obj.findtext("./bndbox/ymax")
        bbox_list.append(xmin)
        bbox_list.append(ymin)
        bbox_list.append(xman)
        bbox_list.append(ymax)
    return bbox_list

#获取image,xml文件路径
img_file_path = r'D:\XM\20220724\datasets\JPEGImages'
xml_file_path = r'D:\XM\20220724\datasets\Annotations'
#创建文件夹保存裁剪后的图
if not os.path.exists("show_out"):
    os.makedirs("show_out")
#获得文件夹内的图片名称,遍历每一张图
img_file = os.listdir(img_file_path)
for img_name in tqdm(img_file):

    img_path = img_file_path +"/" + img_name
    img      = cv2.imread(img_path)

    #获得xml文件前缀
    xml_name = img_name.split("j")[0]
    xml_path = xml_file_path + "/" + "{}xml".format(xml_name)
    #获得bbox坐标
    bbox_list = get_bbox(xml_path)
    #判断xml文件中有几个bbox(最多只有两个bbox)
    if len(bbox_list)<=4:
        xmin,ymin,w,h = int(bbox_list[0]),int(bbox_list[1]),(int(bbox_list[2])-int(bbox_list[0])),\
                        (int(bbox_list[3])-int(bbox_list[1]))
        #使用切片裁剪bbox(还有其他方式)
        img_crop = img[ymin:ymin+h,xmin:xmin+w].copy()
        cv2.imwrite("show_out/{}".format(img_name),img_crop)
    else:
        xmin, ymin, w, h = int(bbox_list[0]),int(bbox_list[1]),(int(bbox_list[2])-int(bbox_list[0])),\
                        (int(bbox_list[3])-int(bbox_list[1]))
        xmin_2, ymin_2, w_2, h_2 = int(bbox_list[4]),int(bbox_list[5]),(int(bbox_list[6])-int(bbox_list[4])),\
                        (int(bbox_list[7])-int(bbox_list[5]))
        img_crop = img[ymin:ymin+h,xmin:xmin+w].copy()
        cv2.imwrite("show_out/{}".format(img_name),img_crop)
        img_crop = img[ymin_2:ymin_2+h_2,xmin_2:xmin_2+w_2].copy()
        cv2.imwrite("show_out/2_{}".format(img_name),img_crop)

 注意事项:

1、xml文件中存储的是xmin,ymin,xmax,ymax格式,需要转换为xmin,ymin,w,h格式

2、切片裁剪的格式是img[ymin:ymin+h,xmin:mxin+w],先高后宽。

你可能感兴趣的:(图像处理基础,python)