目录
需求:
分析:
代码实现:
注意事项:
从标注的数据(一个Images文件,以及对应Annotations文件)中裁剪出目标区域,并将目标区域图片保存在同一个文件夹里。
1、图片名称和对应的xml文件名称相同。
2、一张X光片上不止一个地方有骨折
3、思路:获取图片的路径,用CV读取图片,因为图片名和xml名称前缀一样,可以同时读取xml文件,使用xml.etree.ElementTree解析xml文件获取目标区域的xmin,ymin,xmax,ymax坐标
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],先高后宽。