什么叫网站根目录,公司网站内容如何做,江西网站建设公司电话,三维制图培训班在哪里PIL踩坑记录#xff1a;读取图片方向异常#xff08;yolov5标签错位#xff09;
奇怪的现象
今天用 YOLOv5 做项目时#xff0c;对数据集的标记出现了奇怪的现象#xff0c;在下述测试用例中可明显看到#xff0c;标记框偏离了物体#xff0c;故发文阐述原因和解决方法…PIL踩坑记录读取图片方向异常yolov5标签错位
奇怪的现象
今天用 YOLOv5 做项目时对数据集的标记出现了奇怪的现象在下述测试用例中可明显看到标记框偏离了物体故发文阐述原因和解决方法. ——©️ Sylvan Ding 转载需注明出处 下载了一份数据集UNIMIB2016使用 PIL 读取其中一张照片并标记 bbox. from PIL import Imageimg_name 20151127_120643.jpg
img Image.open(img_name)
img.show()from PIL import ImageDraw
from PIL import ImageFontlabel_name 20151127_120643.txt
with open(label_name) as file:items file.readlines()draw ImageDraw.Draw(img)
for item in items:item item.split()# convert str to intitem[1:] list(map(int, item[1:]))# draw bboxdraw.rectangle([item[1], item[2], item[5], item[6]],outlinered, width20)# add text about order of the pointsfor j, i in enumerate([1, 3, 5, 7]):j j 1draw.text([item[i], item[i 1]], str(j))img.show()# items
# [pane 2008 404 2713 404 2713 915 2008 915\n,
# pizzoccheri 1502 1104 2500 1104 2500 1984 1502 1984\n,
# arrosto 634 602 1193 602 1193 1371 634 1371\n,
# patate/pure 271 539 708 539 708 1408 271 1408\n]# the lash item, whose form is [cls, x1, y1, x2, y2, x3, y3, x4, y4]
# [patate/pure, 271, 539, 708, 539, 708, 1408, 271, 1408]bbox 正确但整张图片好似被旋转了一样。接着使用 cv2 进行相同操作并观察结果。 import cv2
from matplotlib import pyplot as pltimg cv2.imread(img_name)
img cv2.cvtColor(img, cv2.COLOR_BGR2RGB)for item in items:item item.split()# convert str to intitem[1:] list(map(int, item[1:]))# draw bboxcv2.rectangle( img,(item[1], item[2]),(item[5], item[6]),(0, 255, 0), 30)plt.imshow(img)
plt.show()不难发现draw bbox 中使用的坐标均为 [x1,y1], [x3, y3]即对角坐标left-top、right-bottom但 PIL 和 cv2 的结果不同。cv2 中 bbox 错位了而 PIL 中 text 发生了旋转. 为什么会产生这种现象呢从 EXIT 说起
什么是EXIF?
EXIF(Exchangeable Image File)是可交换图像文件的缩写当中包含了专门为数码相机的照片而定制的元数据可以记录数码照片的拍摄参数、缩略图及其他属性信息。Exif 文件实际是JPEG文件的一种遵从JPEG标准只是在文件头信息中增加了有关拍摄信息的内容和索引图。
简单来说Exif 信息就是由数码相机在拍摄过程中采集一系列的信息然后把信息放置在我们熟知的 JPEG/TIFF 文件的头部也就是说 Exif信息是镶嵌在 JPEG/TIFF 图像文件格式内的一组拍摄参数它就好像是傻瓜相机的日期打印功能一样只不过 Exif信息所记录的资讯更为详尽和完备。
EXIF Orientation tag
EXIF Orientation tagEXIF方向参数让你随便照像但都可以看到正确方向的照片而无需手动旋转前提要图片浏览器支持Windows 自带的不支持. ⭐️ 原因解释
造成第一目中“奇怪现象”的原因我将其归纳为在标记数据集时不关注图像的 EXIF Orientation tag而图像本身是含有 EXIF Orientation tag 的。在 PIL 读取图片时创建了 Image 对象其中存有 EXIF Orientation tag根据该标记不仅旋转了图像还旋转了图像的参考系。而 cv2 读取图片时直接生成 numpy.ndarray 数组只根据 EXIF Orientation tag 对图像进行了旋转但并没有旋转图像的参考系
PIL cv2 在绘制矩形框时二者依赖的参考系不同导致标记的错位。而 yolov5 使用的正是 cv2故读取含 EXIF Orientation tag 的图片时会造成 labels 和 图片的错位。
原因证实 PIL 的 PIL.ImageOps.exif_transpose(image)方法可以在读取图片后清除 Image 对象内的 EXIF Orientation tag从而让坐标系不受该 tag 的影响. from PIL import ImageOpsimg Image.open(img_name)
img ImageOps.exif_transpose(img)# draw bbox
...可见清除 EXIF 旋转信息后PIL 所得结果和 cv2 结果一致
⭐️ 解决方法 ❤️ 当然如果你有更好的方法欢迎在评论区留言告诉我哦 from os import listdir
from PIL import Image
import numpy as npimg ./images/
if __name__ __main__:for img_name in listdir(img_path):img Image.open(img_path img_name)img_rectified Image.fromarray(np.asarray(img))img_rectified.save(img_path img_name)上述代码对 ./images/文件夹下所有图片进行了“修正”核心是 img_rectified Image.fromarray(np.asarray(img))(1). 将 img 转化为 ndarray(2). 再将该ndarray转化为Image并保存. (1)、(2) 等同于去除了图片所有的 EXIF 信息这样图片就不会再发生“自动旋转”的现象了. 转载请注明出处©️ Sylvan Ding 参考文献
PIL thumbnail is rotating my image?图片元信息Exif给你详细讲讲EXIF 方向参数 Orientation