偷偷摘套内射激情视频,久久精品99国产国产精,中文字幕无线乱码人妻,中文在线中文a,性爽19p

為什么我的CV模型不好用?沒(méi)想到原因竟如此簡(jiǎn)單……

新聞 機(jī)器學(xué)習(xí)
機(jī)器學(xué)習(xí)專(zhuān)家 Adam Geitgey 近日發(fā)布了一篇文章探討了這一簡(jiǎn)單卻又讓很多人頭痛的問(wèn)題,并分享了他為解決這一問(wèn)題編寫(xiě)的自動(dòng)圖像旋轉(zhuǎn)程序。

計(jì)算機(jī)視覺(jué)模型表現(xiàn)不佳的原因有很多,比如架構(gòu)設(shè)計(jì)缺陷、數(shù)據(jù)集代表性不足、超參數(shù)選擇失誤等。但有一個(gè)很簡(jiǎn)單的原因卻常常被人們忽略:圖像的方向。機(jī)器學(xué)習(xí)專(zhuān)家 Adam Geitgey 近日發(fā)布了一篇文章探討了這一簡(jiǎn)單卻又讓很多人頭痛的問(wèn)題,并分享了他為解決這一問(wèn)題編寫(xiě)的自動(dòng)圖像旋轉(zhuǎn)程序。

我寫(xiě)過(guò)很多有關(guān)計(jì)算機(jī)視覺(jué)和機(jī)器學(xué)習(xí)項(xiàng)目的內(nèi)容,比如目標(biāo)識(shí)別系統(tǒng)和人臉識(shí)別項(xiàng)目。我有一個(gè)開(kāi)源的 Python 人臉識(shí)別軟件庫(kù),算得上是 GitHub 上非常受歡迎的十大機(jī)器學(xué)習(xí)庫(kù)之一。這也意味著我常常收到關(guān)于 Python 和計(jì)算機(jī)視覺(jué)方面的新人提問(wèn)。 

为什么我的 CV 模型不好用?没想到原因竟如此简单……

以我的經(jīng)驗(yàn),有一個(gè)技術(shù)問(wèn)題比其它任何問(wèn)題都更容易讓人受挫——倒不是復(fù)雜的理論問(wèn)題或昂貴 GPU 的問(wèn)題。人們基本上沒(méi)意識(shí)到,幾乎所有人都是以側(cè)向方式將圖像載入內(nèi)存的,而計(jì)算機(jī)在檢測(cè)側(cè)向圖像中的目標(biāo)或人臉時(shí)的能力可沒(méi)那么出色。

數(shù)碼相機(jī)如何自動(dòng)旋轉(zhuǎn)圖像

當(dāng)你在拍攝照片時(shí),相機(jī)會(huì)感知你向哪邊傾斜。當(dāng)你在另一個(gè)程序中查看照片時(shí),它們會(huì)以正確的方向顯示。

为什么我的 CV 模型不好用?没想到原因竟如此简单……

但棘手的問(wèn)題在于, 你的相機(jī)實(shí)際上并沒(méi)有在保存到磁盤(pán)中的文件中旋轉(zhuǎn)圖像數(shù)據(jù)。因?yàn)閿?shù)碼相機(jī)中的圖像傳感器是逐行讀取的,最終匯集成連續(xù)的像素信息流。這能讓相機(jī)更輕松地保存像素?cái)?shù)據(jù),因?yàn)椴还芟鄼C(jī)的姿勢(shì)如何,像素?cái)?shù)據(jù)總是以同樣的順序保存的。

为什么我的 CV 模型不好用?没想到原因竟如此简单……

實(shí)際上,照片能否以正確的方向顯示完全取決于圖像查看器應(yīng)用。相機(jī)在保存圖像數(shù)據(jù)的同時(shí)還會(huì)保存有關(guān)每張圖片的元數(shù)據(jù)——相機(jī)設(shè)置、位置數(shù)據(jù)以及理所應(yīng)當(dāng)?shù)南鄼C(jī)的旋轉(zhuǎn)角度。圖像查看器應(yīng)當(dāng)使用這種信息來(lái)正確地顯示圖像。
 
圖像元數(shù)據(jù)最常見(jiàn)的格式是 Exif(Exchangeable image file forma「可交換圖像文件格式」的縮寫(xiě))。Exif 格式的元數(shù)據(jù)放在相機(jī)保存的 jpeg 文件中。你不能直接從圖像本身讀到這種 Exif 數(shù)據(jù),但可以使用任何知道如何讀取這一數(shù)據(jù)的程序進(jìn)行讀取。
 
下面是使用 Exiftool 讀取的上面的鵝照片的 Exif 元數(shù)據(jù):

为什么我的 CV 模型不好用?没想到原因竟如此简单……

注意 Orientation(方向)這個(gè)數(shù)據(jù)元素。它能指示圖像查看器程序,在屏幕上顯示圖像之前將圖順時(shí)針旋轉(zhuǎn) 90 度。如果程序忘記這么做,圖像就會(huì)側(cè)向顯示。

为什么我的 CV 模型不好用?没想到原因竟如此简单……

為什么這讓很多 Python 計(jì)算機(jī)視覺(jué)應(yīng)用表現(xiàn)不佳?

Exif 元數(shù)據(jù)并非 jpeg 文件格式的原生部分。在 TIFF 文件格式使用了這種元數(shù)據(jù)之后,jpeg 文件格式才加入這種元數(shù)據(jù)。其保持了與老一代圖像查看器的后向兼容性,但這也意味著某些程序根本沒(méi)有費(fèi)心去解析 Exif 數(shù)據(jù)。

numpy、scipy、TensorFlow、Keras 等大多數(shù)用于處理圖像數(shù)據(jù)的 Python 庫(kù)都將自己視為研究通用數(shù)據(jù)數(shù)組的人的科學(xué)工具。所以它們不在乎消費(fèi)者層面的問(wèn)題,比如「圖像自動(dòng)旋轉(zhuǎn)」——即使現(xiàn)在的所有相機(jī)拍照需要這種操作。

這差不多意味著,你用任意 Python 庫(kù)加載圖像時(shí),都會(huì)得到未經(jīng)旋轉(zhuǎn)的原始圖像數(shù)據(jù)?,F(xiàn)在猜猜看,當(dāng)你將側(cè)向的或倒向的圖像輸入人臉識(shí)別或目標(biāo)檢測(cè)模型會(huì)怎樣?因?yàn)槟闾峁┝隋e(cuò)誤的數(shù)據(jù),檢測(cè)器會(huì)提示失敗。

你可能認(rèn)為這個(gè)問(wèn)題僅限于新手或?qū)W生寫(xiě)的 Python 腳本,但事實(shí)并非如此。即使谷歌的旗艦級(jí) Vision API 演示也沒(méi)能正確地處理 Exif 方向:

为什么我的 CV 模型不好用?没想到原因竟如此简单……

谷歌的 Vision API 演示無(wú)法旋轉(zhuǎn)標(biāo)準(zhǔn)的手機(jī)拍攝的縱向圖像。

盡管谷歌的視覺(jué)技術(shù)能成功地檢測(cè)出側(cè)向圖像中存在一些動(dòng)物,但它僅提供了一個(gè)不具體的「Animal(動(dòng)物)」標(biāo)簽。這是因?yàn)槟P蜋z測(cè)側(cè)向的鵝要比檢測(cè)正向的鵝要困難得多。如果在輸入之前先正確地旋轉(zhuǎn)一下,則谷歌 Vision API 會(huì)得到如下的結(jié)果:

为什么我的 CV 模型不好用?没想到原因竟如此简单……

當(dāng)圖像方向正確時(shí),谷歌的檢測(cè)結(jié)果要具體得多——不僅能正確給出「Goose(鵝)」標(biāo)簽,而且置信度分?jǐn)?shù)要高得多,這就好多了。
 
如果你能如本演示中的那樣看到圖像是側(cè)向的,那么這個(gè)問(wèn)題要明顯得多。但問(wèn)題就在于你一般看不到。如今計(jì)算機(jī)上的一般程序都會(huì)以正確旋轉(zhuǎn)后的形式顯示圖像,而不是按照它實(shí)際在磁盤(pán)上存儲(chǔ)的側(cè)向數(shù)據(jù)的形式。所以當(dāng)你想了解你的模型不能起效的原因而查看圖像時(shí),圖像查看器會(huì)以正確的方向顯示,讓你無(wú)從了解你的模型效果差的原因。

为什么我的 CV 模型不好用?没想到原因竟如此简单……

Mac 上的 Finder 總是顯示應(yīng)用了 Exif 旋轉(zhuǎn)后的圖像,這樣就沒(méi)法看到文件中的圖像數(shù)據(jù)實(shí)際上是側(cè)向的。

這不可避免地導(dǎo)致人們?cè)?GitHub 上報(bào)告問(wèn)題,說(shuō)他們使用的開(kāi)源項(xiàng)目根本不行或模型不夠準(zhǔn)確。但事情的本質(zhì)非常簡(jiǎn)單——他們輸入了側(cè)向甚至顛倒的圖像!

解決這個(gè)問(wèn)題

解決方案是,每當(dāng)你用 Python 程序加載圖像時(shí),都執(zhí)行一次 Exif 方向元數(shù)據(jù)檢查,并在有需要時(shí)進(jìn)行旋轉(zhuǎn)。做起來(lái)很簡(jiǎn)單,不過(guò)在網(wǎng)上很難找到能為所有方向正確執(zhí)行旋轉(zhuǎn)的示例代碼。

下面是為任意圖像應(yīng)用正確的方向后再將其載入 numpy 數(shù)組的代碼:

  1. import PIL.Image  
  2. import PIL.ImageOps  
  3. import numpy as np  
  4.   
  5.   
  6. def exif_transpose(img):  
  7.     if not img:  
  8.         return img  
  9.   
  10.     exif_orientation_tag = 274  
  11.   
  12.     # Check for EXIF data (only present on some files)  
  13.     if hasattr(img, "_getexif") and isinstance(img._getexif(), dict) and exif_orientation_tag in img._getexif():  
  14.         exif_data = img._getexif()  
  15.         orientation = exif_data[exif_orientation_tag]  
  16.   
  17.         # Handle EXIF Orientation  
  18.         if orientation == 1:  
  19.             # Normal image - nothing to do!  
  20.             pass  
  21.         elif orientation == 2:  
  22.             # Mirrored left to right  
  23.             img = img.transpose(PIL.Image.FLIP_LEFT_RIGHT)  
  24.         elif orientation == 3:  
  25.             # Rotated 180 degrees  
  26.             img = img.rotate(180)  
  27.         elif orientation == 4:  
  28.             # Mirrored top to bottom  
  29.             img = img.rotate(180).transpose(PIL.Image.FLIP_LEFT_RIGHT)  
  30.         elif orientation == 5:  
  31.             # Mirrored along top-left diagonal  
  32.             img = img.rotate(-90, expand=True).transpose(PIL.Image.FLIP_LEFT_RIGHT)  
  33.         elif orientation == 6:  
  34.             # Rotated 90 degrees  
  35.             img = img.rotate(-90, expand=True)  
  36.         elif orientation == 7:  
  37.             # Mirrored along top-right diagonal  
  38.             img = img.rotate(90, expand=True).transpose(PIL.Image.FLIP_LEFT_RIGHT)  
  39.         elif orientation == 8:  
  40.             # Rotated 270 degrees  
  41.             img = img.rotate(90, expand=True)  
  42.   
  43.     return img  
  44.   
  45.   
  46. def load_image_file(file, mode='RGB'):  
  47.     # Load the image with PIL  
  48.     img = PIL.Image.open(file)  
  49.   
  50.     if hasattr(PIL.ImageOps, 'exif_transpose'):  
  51.         # Very recent versions of PIL can do exit transpose internally  
  52.         img = PIL.ImageOps.exif_transpose(img)  
  53.     else:  
  54.         # Otherwise, do the exif transpose ourselves  
  55.         img = exif_transpose(img)  
  56.   
  57.     img = img.convert(mode)  
  58.   
  59.     return np.array(img)  

之后,你可以將這個(gè)圖像數(shù)據(jù)數(shù)組傳遞給需要的所有標(biāo)準(zhǔn) Python 機(jī)器學(xué)習(xí)庫(kù),比如 Keras 和 TensorFlow。

因?yàn)檫@個(gè)問(wèn)題很常見(jiàn),所以我將其制作成了一個(gè) pip 庫(kù),名為 image_to_numpy,你可以這樣安裝它:

  1. pip3 install image_to_numpy 

你可以在任何 Python 程序中使用它來(lái)實(shí)現(xiàn)正確的圖像加載,比如:

  1. import matplotlib.pyplot as plt 
  2. import image_to_numpy# Load your image file 
  3. img = image_to_numpy.load_image_file("my_file.jpg")# Show it on the screen (or whatever you want to do
  4. plt.imshow(img) 
  5. plt.show() 

 

責(zé)任編輯:張燕妮 來(lái)源: 機(jī)器之心
相關(guān)推薦

2014-10-20 10:53:13

ArubaWi-Fi無(wú)線網(wǎng)絡(luò)

2018-11-21 09:11:42

微軟數(shù)據(jù)中心亞馬遜

2018-01-26 23:23:23

JDBC MySQL數(shù)據(jù)庫(kù)

2021-01-27 18:13:35

日志nginx信息

2023-12-26 15:10:00

處理二進(jìn)制文件

2023-10-25 16:36:06

數(shù)字化轉(zhuǎn)型IT系統(tǒng)

2024-01-04 12:33:17

ChatGPTAI視頻

2021-05-10 07:35:11

SwaggeYApi部署

2017-12-26 15:41:26

2014-11-04 10:15:28

Android

2019-03-04 14:15:43

微軟Windows日歷

2021-08-16 13:44:37

手機(jī)電子日本

2022-03-21 08:55:53

RocketMQ客戶(hù)端過(guò)濾機(jī)制

2019-03-08 10:08:41

網(wǎng)絡(luò)程序猿代碼

2017-02-09 17:00:00

iOSSwiftKVC

2012-12-28 13:47:36

Raspberry PGeek

2022-01-05 17:13:28

監(jiān)控HTTPS網(wǎng)站

2021-11-29 05:37:24

Windows Def操作系統(tǒng)微軟

2020-08-14 08:19:25

Shell命令行數(shù)據(jù)

2009-04-28 07:48:29

蓋茨打工基金會(huì)
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)