@致力于文化傳播給企業帶來的價值

相機的Exif信息會導致計算機視覺模型效果不佳?

123
發表時間:2019-10-10 16:40作者:成名來源:搜狐科技網址:http://www.rmmkax.live

在開發和使用計算機視覺(CV)模型的過程中,由于NumPy、TensorFlow和電腦上的圖片查看器在處理Exif上存在著差異,讓這個問題變得十分隱秘。

Adam是一位知名的機器學習課程博主,他的博客內容非常實用,幾乎篇篇都能收獲上千贊,足見其受歡迎的程度。


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

Exif信息害死人

普通智能手機或者相機拍照時,如果手持方向發生變化,內部的重力感應器件會告訴設備,照片究竟哪個邊是向上的。

當我們在手機、相機或者電腦的Photoshop軟件上查看照片時,完全沒有問題,就像這樣:



然而眼見并非為實,實際圖像的像素數據不會旋轉。這是由于圖像傳感器是對連續的像素信息流進行逐行讀取,因此你無論縱向和橫向握持相機,圖像都是按照一個方向進行存儲。

那么拍照設備和電腦為什么就能按照正確的方向顯示圖片呢?這是因為照片里還保存著一組元數據,稱之為Exif,即可交換圖像文件格式(Exchangeable image file format)。

Exif中包含著照片的像素數、焦距、光圈等信息,其中還有一個方向(Orientation)的數據。

上圖中Orientation一項的參數是Rotate 90 CW,意思是圖像在顯示前需要順時針旋轉90度。如果圖片查看程序沒有執行此操作,你就只能擰著脖子看了。

Exif原先是用在TIFF圖像格式上,后來才加入到JPEG圖像格式中,而圖像數據集中的圖片大多是JPEG格式。

一些程序為了保持向后兼容性,不會去解析Exif數據。大多數用于處理圖像數據的Python庫(如NumPy、SciPy,TensorFlow,Keras等)就是這樣的。

這意味著當你使用這些工具導入圖像時,都將獲得原始的未旋轉圖像數據。如果把這些側躺著或上下顛倒的圖像輸入到CV模型中,會得到錯誤的檢測結果。

這個問題看起來很愚蠢,似乎初學者會犯這樣的低級錯誤。但事實并非如此!甚至連Google云上的視覺API Demo也無法正確處理Exif方向問題:

如果我們把圖像旋轉到正確的方向再上傳,檢測的結果與上圖相比將完全改變:

當我們在電腦上查看圖片時完全沒問題,但是一用到模型中就不正常。因此很難發現問題的所在。

這也導致一些開發者在Github上提問,抱怨他們正在使用的開源項目已損壞,或是模型不夠準確。但是實際上問題要簡單得多,只是圖片的方向錯了!

解決方法

解決以上問題的方法就是,在導入圖像時檢查它們的Exif數據,在必要時旋轉圖像。Adam已經寫好了一段代碼:

importPIL.Image

importPIL.ImageOps

importnumpy asnp

defexif_transpose(img):

ifnotimg:

returnimg

exif_orientation_tag = 274

# Check for EXIF data (only present on some files)

ifhasattr(img, "_getexif") andisinstance(img._getexif, dict) andexif_orientation_tag inimg._getexif:

exif_data = img._getexif

orientation = exif_data[exif_orientation_tag]

# Handle EXIF Orientation

iforientation == 1:

# Normal image - nothing to do!

pass

eliforientation == 2:

# Mirrored left to right

img = img.transpose(PIL.Image.FLIP_LEFT_RIGHT)

eliforientation == 3:

# Rotated 180 degrees

img = img.rotate( 180)

eliforientation == 4:

# Mirrored top to bottom

img = img.rotate( 180).transpose(PIL.Image.FLIP_LEFT_RIGHT)

eliforientation == 5:

# Mirrored along top-left diagonal

img = img.rotate( -90, expand= True).transpose(PIL.Image.FLIP_LEFT_RIGHT)

eliforientation == 6:

# Rotated 90 degrees

img = img.rotate( -90, expand= True)

eliforientation == 7:

# Mirrored along top-right diagonal

img = img.rotate( 90, expand= True).transpose(PIL.Image.FLIP_LEFT_RIGHT)

eliforientation == 8:

# Rotated 270 degrees

img = img.rotate( 90, expand= True)

returnimg

defload_image_file(file, mode='RGB'):

# Load the image with PIL

img = PIL.Image.open(file)

ifhasattr(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)

returnnp.array(img)

加入以上代碼后,就可以正確地將圖像導入Keras或TensorFlow了。

如果覺得麻煩,Adam還把上面的代碼打包好了,在GitHub上這個項目叫做image_to_numpy。一行代碼就可以完成安裝:

pip3 install image_to_numpy

以后,你在自己的Python代碼中加入這樣幾句即可。

importmatplotlib.pyplot asplt

importimage_to_numpy

# Load your image file

img = 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

大咖軟文網:為中小企業提供優質全方位軟文營銷服務,努力打造軟文發布數字化營銷傳播平臺,致力于文化傳播給企業帶來的價值!

工作時間

周一至周五:8:30-20:00

周六至周日:8:30-18:00


聯系電話:15919903290

電子郵箱:[email protected]



 新手上路
幫助中心
淘寶店鋪        
服務咨詢
快速通道
快速登錄
免費注冊,超低價格發稿推廣
在線客服
 
 
——————
銷售經理
15919903290