这里是目录标题
import tensorflow as tf # 深度学习
import matplotlib.pyplot as plt # 画图
from matplotlib.patches import Rectangle # 绘制矩形框
from lxml import etree # 读取矩形框信息
import numpy as np
import glob # 读取图片路径信息
我是用的是2.0.0版本的tensorflow,
电脑是2020 MacBook Pro 13寸,暂时还没查到怎么打开GPU模式,所以后续训练模型可能都只训练1个epoch。
(如果有大佬知道怎么开的话,please私我一下,必有重谢!!!)
tf.__version__
>>>'2.0.0'
tf.test.is_gpu_available() # 是否使用GPU
>>>False
读取单张图片数据,并根据信息绘制矩形框
# 读取图片数据
img = tf.io.read_file('./数据集/图片定位与分割数据集/images/Abyssinian_1.jpg')
img = tf.image.decode_jpeg(img) # 数据解码
img.shape
>>>TensorShape([400, 600, 3])
随便画一张,看我们的路径是否正确。
plt.imshow(img)
读取矩形框数据(.xml文件)
xml = open('./数据集/图片定位与分割数据集/annotations/xmls/Abyssinian_1.xml').read()
# 转化为html格式(在爬虫课程中会有)
sel = etree.HTML(xml)
# '//size//text()'表示:提取在size目录下,所以子目录的文件
sel.xpath('//size//text()')
>>>['600', '400', '3']
# '//size/width/text()'表示:在size目录下的width目录中的文本
width = int(sel.xpath('//size/width/text()')[0])
width
>>>600
height = int(sel.xpath('//size/height/text()')[0])
height
>>>400
depth = int(sel.xpath('//size/depth/text()')[0])
depth
>>>3
下边这四个是比较重要的数值,相当于矩形框的定点坐标
# 同理取出其他的参数
bndbox = sel.xpath('//bndbox//text()')
bndbox
>>>['333', '72', '425', '158']
xmin, ymin, xmax, ymax = int(bndbox[0]), int(bndbox[1]), int(bndbox[2]), int(bndbox[3])
xmin, ymin, xmax, ymax
>>>(333, 72, 425, 158)
根据数值绘制出矩形框
# 绘制图片
plt.imshow(img)
# 构建矩形框,参数fill:是否进行填充
rect = Rectangle((xmin, ymin), width=(xmax-xmin), height=(ymax-ymin), fill=False, color='red')
# 锁定图片
ax = plt.gca()
# 添加矩形框
ax.axes.add_patch(rect)
plt.show()
图片 / xml数据的预处理
当我们对图片进行resize后,矩形框坐标也需要随之改变;
⚠️给定的矩形框与原图想的大小有关,所以在对图片进行缩放后,对矩形框进行同比例缩放,否则会发现未知的偏移!
# 对原图进行缩放
new_img = tf.image.resize(img, [224, 224]) # 缩放至224 * 224
new_img = new_img/255 # 归一化==>[0,1]
按照比例对矩形框的四个顶点坐标进行缩放
# 按照比例对矩形框的四个顶点坐标进行缩放
xmin = (xmin/width)*224
ymin = (ymin/height)*224
xmax = (xmax/width)*224
ymax = (ymax/height)*224
# 重新绘制缩放后的图片
plt.imshow(new_img)
# 构建矩形框,参数fill:是否进行填充
rect = Rectangle((xmin, ymin), width=(xmax-xmin), height=(ymax-ymin), fill=False, color='red')
# 锁定图片
ax = plt.gca()
# 添加矩形框
ax.axes.add_patch(rect)
plt.show()
⚠️则可以看出,我们进行回归的目标值是 xmin/width,ymin/height,xmax/width,ymax/height这四个比值,
而不是xmin, ymin, xmax, ymax。因为,比值不会因为缩放而改变在图像中的位置。