零、任务描述:
xml文件中只有点坐标和其中可以结对的点坐标。要求将结对点坐标形成的区域裁剪出来并进行分类组成正样本,然后对所有点坐标两两结对,剔除可以两两结对的组合,然后进行裁图行程负样本。
本文将对过程中的关键点进行梳理,并对常见错误的解决方案进行说明。
xml格式如下:
-<point>
<name>0</name>
<x1>404</x1>
<y1>70</y1>
</point>
-<port>
<name>port</name>
<pose>Unspecified</pose>
-<portbox>
<x1>404</x1>
<y1>70</y1>
<x2>395</x2>
<y2>185</y2>
<portType>0</portType>
<portAngle>90</portAngle>
</portbox>
</port>
一、环境准备:
我这里使用的是vscode开启anaconda虚拟环境,关键库如下:
python、opencv-python、opencv-contrib-python、PIL、numpy等
下面是我导入语的库:
import sys,os
import numpy as np
from matplotlib import pyplot as plt
import xml.etree.ElementTree as ET
from math import * #实现弧度变换
import cv2
import math
import PIL
from PIL import Image
import os.path
import glob
二、读取xml文件:
关键代码如下:
for img_file in os.listdir(img_path): #遍历图片文件夹
if img_file[-4:] in ['.png', '.jpg']: #判断文件是否为图片格式
if os.path.exists(xml_name): #判断与图片同名的标签是否存在,因为图片不一定每张都打标
root = ET.parse(xml_name).getroot() #利用ET读取xml文件
三:定义旋转矩阵:
在裁剪的过程中,需要对图像旋转:
def rotateImage(image, angle):
image_center = tuple(np.array([(int(x0)+int(x1))/2,(int(y0)+int(y1))/2]))
rot_mat = cv2.getRotationMatrix2D(image_center,angle,1.0)
result = cv2.warpAffine(image, rot_mat, image.shape[1::-1],flags=cv2.INTER_LINEAR)
return result
四、正负样本输出:
在裁剪的过程中判断图像是否正常
fileObj = open(path, 'rb') # 以二进制形式打开
buf = fileObj.read()
if not buf.startswith(b'\xff\xd8'): # 是否以\xff\xd8开头
bValid = False
elif buf[6:10] in (b'JFIF', b'Exif'): # “JFIF”的ASCII码
if not buf.rstrip(b'\0\r\n').endswith(b'\xff\xd9'): # 是否以\xff\xd9结尾
bValid = False
else:
Image.open(fileObj).verify()
except Exception as e:
bValid = False
print(e)
except Exception as e:
return False
return bValid
常见错误1
错误提示:TypeError: src is not a numpy array, neither a scalar
原因分析:使用image.open打开图像后,进行resize操作之后,不能直接使用cv2.imwrite保存图像。
解决方式:在cv2.imwrite之前,使用np.asarray进行数据转换。例如
obj_img2 = np.asarray(obj_img1)
常见错误2
错误现象:裁剪后的图像颜色不一致,偏蓝。
原因分析:因为OpenCV是以BGR模式读入图片,如果想要正常显示图片,则需要改成RGB格式。
解决方式:格式转换
obj_img2=cv2.cvtColor(obj_img2,cv2.COLOR_BGR2RGB)
常见错误3
错误报错:OSError: cannot identify image file
原因分析:图像格式出错。
解决方式:使用自定义的函数 is_valid_image()函数判断图像是否正常。
参考链接:
Python XML 解析
PIL及matplotlib:OSError: cannot identify image file錯誤及解決方式
利用Python获取VOC中的xml标注文件中的目标框
Python:批量按xml标注将目标crop剪切图片并按类保存到相应文件夹
python利用文件夹下xml格式标签文件批量裁剪出图片中的目标(文件夹、图片名称、目标框数量无限制,逐行注释)
解析大量xml文件坐标位置,裁剪图片
Python读取xml文件后,裁剪标注图片,并扩容数据
解决使用anaconda VSCODE无法import cv2问题
Python - 深度学习系列3-图像区域标注及抠图