目前我理解图像定位的概念是,在图片中识别出目标,然后再将目标标注出来。对图像定位方法的分析共分为三部分,第一部分是图像标注的基础(也就是该部分),第二部分是数据集的读取与处理,第三部分是图像识别与定位。
一、The Oxford-IIIT Pet Dataset介绍
这部分采用的数据集是The Oxford-IIIT Pet Dataset,该数据集包含37类宠物图像,每类图像包含约200张图片,图像在比例,姿势和光线方面有很大的变化。所有图像都具有种类、头像拉框和像素级分割的相关实况注释。
二、引入相关依赖包
import tensorflow as tf
import matplotlib.pyplot as plt
%matplotlib inline
from lxml import etree
from matplotlib.patches import Rectangle
import numpy as np
import glob
三、查看图片及对应注释文件
1、图像读取显示
下面读取一张图片。
img = tf.io.read_file(r'/home/wchw/资料/人工智能/下载数据集/The Oxford-IIIT Pet Dataset/images/Abyssinian_1.jpg')
img = tf.image.decode_jpeg(img)
查看图像的形状
img.shape
输出结果为TensorShape([400, 600, 3])
显示图片
plt.imshow(img.numpy())
plt.show()
2、图片注释的读取
每张图片均对应一个xml文件,xml文件描述了图片的属性,以及目标在图片中的位置,以下是上面的这张图片对应的xml。
比如,bndbox部分代表目标在图片的位置。
读取Abyssinian_1.jpg对应的xml文件
xml = open(r'/home/wchw/资料/人工智能/下载数据集/The Oxford-IIIT Pet Dataset/annotations/xmls/Abyssinian_1.xml').read()
sel = etree.HTML(xml)
可以在描述文件中读取对应图片的长宽
width = sel.xpath('//size/width/text()')[0]
width
显示600
height = sel.xpath('//size/height/text()')[0]
height
显示400
读取目标在图像中的坐标区间
xmin = sel.xpath('//bndbox/xmin/text()')[0]
ymin = sel.xpath('//bndbox/ymin/text()')[0]
xmax = sel.xpath('//bndbox/xmax/text()')[0]
ymax = sel.xpath('//bndbox/ymax/text()')[0]
xmin, ymin, xmax, ymax
显示为('333', '72', '425', '158')
进行数据类型转换
width = int(width)
height = int(height)
xmin = int(xmin)
ymin = int(ymin)
xmax = int(xmax)
ymax = int(ymax)
3、目标标绘
下面用矩形讲目标从图像中标识出
plt.imshow(img.numpy())
rect = Rectangle((xmin, ymin), (xmax-xmin), (ymax-ymin), fill=False, color='red')
ax = plt.gca()
ax.axes.add_patch(rect)
plt.show()
我们知道,图像Abyssinian_1.jpg的尺寸为600*400,其他图像的尺寸却不一定是这个数值,而是各种大小的尺寸,即尺寸不统一。为了进行训练学习,需要将尺寸进行统一,我将图片尺寸统一为224*224.
下面读取图片、设置尺寸大小、归一化
img = tf.io.read_file(r'/home/wchw/资料/人工智能/下载数据集/The Oxford-IIIT Pet Dataset/images/Abyssinian_1.jpg')
img = tf.image.decode_jpeg(img)
img = tf.image.resize(img, [224, 224])
img = img/255
读取目标位置,并将进行类型转换。
xmin = sel.xpath('//bndbox/xmin/text()')[0]
ymin = sel.xpath('//bndbox/ymin/text()')[0]
xmax = sel.xpath('//bndbox/xmax/text()')[0]
ymax = sel.xpath('//bndbox/ymax/text()')[0]
xmin = int(xmin)
ymin = int(ymin)
xmax = int(xmax)
ymax = int(ymax)
由于图片的大小改变了,那个目标的位置也要进行相应的变化,如下
xmin = xmin*224/width
ymin = ymin*224/height
xmax = xmax*224/width
ymax = ymax*224/height
下面进行图像显示及目标的绘制
plt.imshow(img.numpy())
rect = Rectangle((xmin, ymin), (xmax-xmin), (ymax-ymin), fill=False, color='red')
ax = plt.gca()
ax.axes.add_patch(rect)
plt.show()