为什么别人常用的面部识别,目标检测到开源模型,到了初学者手中,效果连眼睛都看不到呢?这可能有很多理由,但也有它“愚蠢”的情况。

最近Medium的博主Adam Geitgey指出了面向初学者极其简单容易错过的要点。“相机的Exif信息”。

计算机视觉(CV)模型的开发和使用过程中,NumPy、TensorFlow和计算机上的图片查看器在处理Exif上存在差异,因此这个问题变得非常隐秘。

Adam是机械学习课程的著名博主,博客的内容非常实用,几乎所有的报道都很受欢迎。

他在最新的文章中指出CV模型处理Exif存在的缺失,以及补救的方法,下面是他的文章的主要内容。

Exif信息会死人

用普通的智能手机和照相机拍照的时候,如果手的方向改变的话,内部内置的重力传感器会告诉你照片哪个是向上的。

在手机和相机电脑的照片店看照片也完全没有问题

但是,实际图像的像素数据不会旋转。这是因为图像传感器会渐进地读取连续的像素信息流,无论是纵向还是横向相机,图像都会单向存储。

那么,为什么相机和电脑能在正确的方向上显示图像呢。这是因为照片中保存着被称为Exif的元数据,可以交换Exchangeable image file format。

Exif包含照片像素数、焦距、光圈等信息。其中也有定向的数据。

上图的Orientation项参数为Rotate 90CW,表示在显示图像之前必须顺时针旋转90度。如果这个操作没有执行,你只能扭头看。

Exif原本是在TIFF图像格式中使用的,后来被编入JPEG图像格式中。图像数据集的图像大多是JPEG。

有些程序不分析Exif数据,因为它保持向后兼容性。许多用于处理图像数据的Python库(NumPy、SciPy、TensorFlow、Keras等)都是这样。

这意味着当你使用这些工具导入图像时,都会得到原来的非旋转图像数据。如果在CV模型中输入横向或反向图像,则会得到错误的检测结果。

乍一看是个愚蠢的问题,初学者好像会犯这样的初步错误。但是,不是这样的!即使是谷歌云上的可视API Demo,也无法正确处理Exif方向性问题。

如果你把图像旋转到正确的方向上传,检测结果就会和上面的图像完全不同

在电脑上看图像的时候没有问题,但是做模型的话就不顺利了。因此,很难知道哪里有问题。

结果,一些开发商在Github上收到了自己使用的开源项目损坏、型号不正确等投诉。但实际问题要简单得多,只是画的方向不对!

解决方案

解决这一问题的方法是在导入图像时检查这些Exif数据,并根据需要旋转图像。Adam写了代码。

import pil.imageopsimport numpy as npdef exif_transpose(img): if not img:return img EXIF _orientation_tag = 274 # Check for EXIF data (only present on some files) if hasattr(img,_getexif) and isinstance(img._getexif(), dict) and exif_orientation_tag in img._getexif():EXIF _data = img._getexif() orientation = EXIF _data[EXIF_orientation_tag]#Handle EXIF orientation==1:#正规image-nothing to do!pass elif orientation==2。#irrored left to rightimg.transpose(pil.image.flip_left_right)elif orientation=3Rotated180degrees[img]。rotate(180)elif orientation=4:#Mirrored top to bottomimg。rotate(180).transpose(pil.image.flip_left_right)elif orientation=5:#Mirrored along top-left diagonal img.rotate(-90,expand=True).transpose(pil.image.flip_left_right)elif orientation=6。#Rotated90degreesimg.rotate(-90,expand=True)elif orientation=7:#Mirrored along top-right diagonal img.rotate(90,expand=True).transpose(pil.image.flip_left_right)elif orientation=8Rotated 270 degrees img = img.rotate(90, expand=True) return imgdef load_image_file(file, mode='RGB'):# Load the image with PIL img = pil.image.open (file) if hasattr(pil.imageops, 'exif_transpose'):# Very recent versions of PIL can do exit transpose internally img = PIL imageops.exif _transpose(img) else:# Otherwise, do the exif transpose ourselves img = exif_transpose(img) img = img.convert(mode) return np.array(img)

加入以上代码后,可以正确将图像导入Keras和TensorFlow。

如果麻烦的话,也要打包上的代码。在GitHub中,该项目包含image_to_它被称为numpy。可以用一行代码安装

pip3 install image_to_numpy

然后,在自己的Python代码中加入这个短语就可以了。

import matplotlib。pyplot as pltimport image_to_numpy# Load your image fileimg =image_to_numpy.load_image_file(my_file.jpg)#Show it on the screen(or whatever you want to do)plt.imshow(img)plt.show()

是传送门

译文链接:。

https://medium.com/@ageitgey/the-dumb-reason-your-fancy-computer-vision-app-isnt-working-exif-orientation-73166c7d39da

旋转图像的image_to_numpy:

https://github.com/ageitgey/image_to_numpy