ImageMagick 範例 --
鏡頭校正
- 索引
-
ImageMagick 範例前言與索引
-
鏡頭校正簡介
-
非縮放約束
-
預先定義的參數集
-
從頭開始校準
-
範例
-
鍵盤範例(作者:El-Supremo)
-
校正鏡頭失真(PDF)
鏡頭校正簡介
魚眼鏡頭和低成本廣角鏡頭(或更確切地說是設定為短焦距的變焦鏡頭)通常會產生明顯的桶形失真。然而,這種失真可以通過對數位照片應用合適的演算法轉換來進行大部分校正。Panorama Tools 引入並由 PTlens 使用的最常用的鏡頭校正演算法之一,ImageMagick 也提供了這種演算法,作為 桶形校正失真係應方法。在這種解決問題的方法中,失真由四個變換參數a、b、c、d
控制,必須明智地選擇這些參數,以便校正特定鏡頭(或更確切地說是設定為特定焦距的變焦相機)產生的失真。很難通過反覆試驗找到這些參數的合適值。在下文中,我們將描述如何通過使用 Hugin 有效地確定該模型的鏡頭校正參數,Hugin 是一個用於 Panorama Tools 的免費圖形用戶介面,適用於各種作業系統。如果您不想處理鏡頭校正的細節,您可以跳過本頁面的其餘部分,只需購買 PTlens,它以合理的價格為大量數位相機和鏡頭提供複雜的鏡頭校正(通過使用其龐大的鏡頭資料庫)。如今,一些數位相機(例如尼康 P7000)甚至在其內部影像處理步驟中加入了鏡頭校正。對於使用不提供這種可能性的相機拍攝的照片,ImageMagick 使您能夠將鏡頭校正整合為更大影像處理腳本的一個步驟。以下文字是論文 校正鏡頭失真(PDF)(處理事故重建中的應用)的縮略版。這裡給出的解釋是一種更為實用的方法,重點是如何掌握適當的鏡頭校正參數。非縮放約束
如 桶形失真 中所述,桶形失真由以下數學公式定義R = ( a * r^3 + b * r^2 + c * r + d ) * r其中
r
是到數位照片幾何圖像中心的距離,R
是原始圖像中的等效半徑。與此類映射一樣,上述等式定義了一種“顏色查找函數”,即在哪裡查找半徑為 r
的像素的顏色。半徑 r
和 R
通過較小圖像尺寸的一半(即通常是圖像的高度)進行歸一化,這樣對於圖像上下邊緣的中點,r = R = 1
。在校正數位照片時,我們應該注意非縮放約束a + b + c + d = 1顯然,對於
r
= 1,它給出 R
= 1。Panorama Tools 通過其他參數計算參數 d
d = 1 - a - b - c給我們留下三個自由模型參數,因此參數
d
通常被省略。如果省略,ImageMagick 將通過非縮放約束自動計算 d
。因此,用於鏡頭校正的典型 ImageMagick 命令行看起來像magick input.jpg -distort barrel '0.06335 -0.18432 -0.13008' output.jpg將
d
的計算留給 ImageMagick。我們在這裡討論的 Panorama Tools 的鏡頭校正方法假設鏡頭的光軸和圖像的中心是相同的,這在實踐中並不嚴格(由於製造公差)。此外,它還忽略了像八字鬍變形這樣的效應。然而,在實踐中它似乎工作得非常精確。![[圖表]](curve.gif)
a = 0.05,b = -0.25,c = 0.05
),該關係通常在 0 到 1.5 的範圍內使用(縱橫比 3:2),穿過點 (0,0) 和 (1,1),並且對於 r > 1
必須遞減。現成的參數集
PTlens 目前的鏡頭數據庫是該程序的“精髓”,它經過加密,只能由 PTlens 本身讀取。然而,直到 2006 年 2 月,PTlens 的數據庫都是用 XML 格式編碼的,即一種易於編輯的文本格式。PTlens 的 XML 數據庫的 2006 版本仍然可以在Hugin 的 SourceForge 網站上(合法地)獲得,並提供許多舊相機型號的數據。當 PTlens 的數據庫被加密後,Hugin 的作者嘗試建立一個免費的 XML 編碼鏡頭數據庫作為替代方案。這個數據庫被稱為LensFun,可以下載。它帶有一個完整的編程接口,但您基本上只需要 XML 文件中相機的信息。例如,曾經流行的尼康 Coolpix 995 的鏡頭校正參數可以在文件compact-nikon.xml
中找到,該文件位於目錄 \data\db
中。可以使用文本編輯器或 XML 查看器檢查該文件
|
a
和 c
設置為零,即畸變僅由二階項 b
描述。請注意,許多鏡頭的 a
和 c
參數也會有值,並且這些值也應該以類似的方式進行插值。如果我們有一張用設置為最短焦距的尼康 Coolpix 995 拍攝的照片 DSCN0001.jpg
,則可以使用 ImageMagick 通過以下方式校正該照片
|
_pt
是 PTlens 用來標記已校正影像的記號。)針對提供的六個焦距,校正係數 b
可以從 XML 檔案中讀取。對於其他焦距,可以透過在兩個相鄰焦距之間內插來決定適當的值。或者,b
對焦距 f
的依賴性可以透過以下多項式來近似b = 0.000005142 * f^3 - 0.000380839 * f^2 + 0.009606325 * f - 0.075316854因此,第一步是使用從 EXIF 資訊中讀取的焦距來計算鏡頭校正參數
b
,然後在第二步中,使用此值作為 b
參數來執行鏡頭校正(即桶狀變形)。Windows 部分顯示了一個 VBScript 範例,其中使用了上述方程式,並透過 magick identify
從 Nikon Coolpix 995 照片中提取焦距。從頭開始校正
基本方法
在確定鏡頭參數時,所有程式都依賴於相同的範例:理想的透視映射應該將真實世界的直線映射到影像中的直線。因此,如果已知一組真實世界點 P0、P1、...、Pn 位於一條直線上,則它們的影像 p0、p1、...、pn 也必須落在同一條直線上。任何偏離此規則的情況都必須歸因於鏡頭變形。我們需要兩個點來確定定義一條直線的兩個參數(例如斜率和 y 軸上的交點)。提供的每個額外點將提供另一個方程式來確定鏡頭校正參數。因此,如果我們的函數方法只有一個自由參數b
(如上所述的 Nikon Coolpix 995),我們必須至少提供真實世界直線上的三個點及其影像,才能確定所需的鏡頭校正參數 b
。更具體地說:變形模型僅使用參數 b
,也就是說,校正後影像的坐標 X1, Y1
可以透過以下公式從數位照片的坐標計算得出r = s * sqrt(x1^2 + y1^2) X1 = [(1-b) + b r^2] * x1 Y1 = [(1-b) + b r^2] * y1 Y1 = k1 * X1 + k2這會為同一條直線上提供的每個點產生一個方程式
[(1-b) + b r^2] * y1 = k1 * [(1-b) + b r^2] * x1 + k2 with: r = s * sqrt(x1^2 + y1^2)因此,三個真實世界點及其對應的影像點足以確定描述直線和鏡頭變形
k1、k2、b
的參數。實際上,真實世界點的坐標很少是已知的,因此需要三個以上的點來確定所需的參數。大多數校正軟體使用直線的矩形網格(通常是棋盤格)來生成一組方程式,然後透過非線性最小平方法擬合來計算映射參數。有些程式會自行生成一組控制點,通常使用預先定義的模板;其他程式則需要使用者從校正影像中選擇控制點。使用 Hugin 確定鏡頭參數集
接下來,我們將演示如何透過使用 Hugin 來確定一組鏡頭校正參數。Hugin 的網站上也有一個現成的「簡易鏡頭校正教學」,但在撰寫本文時(2014 年),它似乎過於簡單,無法提供可靠的參數,無法在日後用於各種校正。首先,您必須取得合適的測試圖案。基本上,一個包含大約 10 × 7 個正方形的棋盤格圖案,印在 ISO 216 A3 或類似的紙張上就可以了,而且經常被使用。然而,低成本的變焦鏡頭(所謂的 變焦鏡頭)在校正過程中應設定為無限遠對焦,因為它們的實際焦距可能與嵌入在 EXIF 中的近距離對焦焦距有很大差異。對於定焦鏡頭,您也可以使用棋盤格測試圖案,這在校正魚眼鏡頭時尤其推薦使用,因為可能難以找到一個足夠大的真實世界物體來覆蓋其視野。因此,特別是在校正變焦鏡頭/變焦相機時,您應該拍攝現代建築物的照片,如 PTlens 網站 上所建議的那樣。請遵循該網站上提供的說明。照片可能會顯示透視變形啟動 Hugin,點擊第一個標籤上的「新增影像...」按鈕,並打開校準影像。(請參閱 hugin.sourceforge.net 以取得 Hugin 介面的螢幕截圖。)在標籤按鈕處,將「最佳化」設定為「自訂參數」(這將會新增一個名為「最佳化器」的標籤,否則您將不會看到)。在「拼接器」標籤上,將「投影」設定為「直線」。在「控制點」標籤上,您會看到您的測試照片出現兩次,您可以透過在兩個版本的照片中選取這些點群組,來定義位於同一條直線上的點集。但請勿在兩個版本中選取完全相同的點,以免這些點在兩張影像中完全相同,因為這會誤導最佳化器採取簡單的方式,並確定一對一對應的參數。相反地,您應該在兩個版本的影像中選擇同一條直線上的不同點。為了測試目的,您可以定義幾個這樣的點集,最好靠近影像邊緣,那裡的直線扭曲較大。您會發現,在 Hugin 中定義這樣的點集是一件相當繁瑣的事情(這可能是 lensfun 資料庫如此之小的原因之一)。
然後切換到「最佳化器」標籤,並透過按住 Ctrl 鍵並用滑鼠左鍵點擊來選擇要最佳化的參數。(請參閱標籤頂部的提示。)我建議最佳化「Yaw(y)」、「Pitch (p)」和鏡頭參數「a」、「b」和「c」。水平視角「Hfov (f)」是根據測試影像中的 EXIF 資料計算出來的,使用 FocalLengthIn35mmFilm 項目f
Hfov = 2 × arctan (18 mm / f)其中 18 公釐是 35 公釐底片寬度的一半(其尺寸為 36 × 24 公釐)。然後按下「立即最佳化!」按鈕。對於廣角鏡頭,產生的參數「a」、「b」和「c」應低於 0.01,對於魚眼鏡頭,則應低於 0.1。如果數值較大,則表示最佳化可能失敗。如果是這樣,請檢查「控制點」標籤上的點集:控制點的順序可能錯誤,或者未正確與其對應的線條關聯。最佳化器似乎也對提供的起始集(數學上稱為起始向量)很敏感,也就是說,將所有參數設定為零可能是錯誤的選擇。您可以透過雙擊「最佳化器」標籤上的數值,或勾選標籤頁右下角的「在最佳化之前編輯腳本」核取方塊,來編輯起始向量。這將會在最佳化之前顯示一個文字方塊,讓您編輯 Hugin 專案檔案的相應部分。在重新啟動最佳化器之前,將起始向量 a、b、c 設定回
a0.0 b0.0 c0.0
(或其他合適的數值)。經驗顯示,將「a」設定為某個正數值可能會有幫助,特別是對於魚眼鏡頭而言。對於配備定焦鏡頭的相機,只需進行一次校準即可。對於配備變焦鏡頭的相機,則必須透過校準大約五個不同的焦距,來涵蓋整個焦距範圍。在確定了這樣的參數集之後,請透過以下方式在 ImageMagick 中進行測試:
magick calibration_image.jpg -distort barrel 'a b c' flat.jpg |
a b c
替換為剛才確定的數值。輸出影像中的線條應該完全筆直,否則表示最佳化失敗,需要使用不同的起始向量或修正後的控制點集重新執行最佳化。定義點集
若要進行嚴謹的校準,建議手動編輯 Hugin 專案檔案,並透過其他方式定義點座標和點集。專案檔案是一個副檔名为 PTO 的純文字檔案,您可以使用簡單的文字編輯器開啟它,並提供一個點列表。在其# control points
部分中的一行看起來像這樣c n0 N0 x175.0 y87.8 X1533.3 Y62.6 t3其中
x, y
是來源影像(標籤左側的影像)中的像素坐標,而 X, Y
是目標影像(標籤右側的影像)中的像素坐標 - 在這個特殊情況下,它們實際上是同一影像的兩個版本。(通常這些會是全景圖中並排的兩個不同影像。)開頭的 c n0 N0
是標準代碼,結尾的 t3
是關聯直線的編號,從索引 3 開始。從上面的例子可以看出,像素坐標可能會有小數部分。當然,x, y
和 X, Y
必須位於同一條直線上。但是,它們不能相同,因為在這種情況下,優化器將無法工作(見上文)。保證這一點的最簡單方法是在兩個影像中使用相同的點,但目標坐標的順序相反,例如在左側影像中使用 p1、p2、p3、p4,在右側影像中使用 P4、P3、P2、P1。使用點選工具確定來源影像中的像素坐標。您可以使用任何可以儲存此類數據的影像檢視器來執行此操作。一個平台獨立的工具是 Fiji。我(在 Windows 下工作)使用 WinMorph 中的折線來執行此操作。選擇點時,您應該遵循預先定義的策略,例如在每條(或多或少)水平線上選擇相同數量的點,從左到右(即在整個影像中遵循鋸齒線,就像電視映像管中的陰極射線)。這樣的策略將簡化目標點坐標的排序。然後,可以手動或藉助軟體工具建立定義來源和目標點坐標的文字檔案行。(我使用 Excel VBA 子常式來執行此任務。)準備就緒後,將點列表複製到 PTO 檔案的相應部分,儲存並使用 Hugin 重新開啟它。結果應如下所示ZIP檔案olympus_c2500l.zip中提供了一個包含校準圖像和相應Hugin專案的現成範例。 從相機建立的縮略圖進行反向工程
在幾種情況下,我們已經有一對圖像,一個是桶狀變形的,另一個是已經校正的。此校正可能是使用其他鏡頭校正軟體執行的,該軟體沒有告訴我們校正參數。此外,許多現代相機(2019年)都提供對JPEG圖像進行內部鏡頭校正的功能。但是,此功能通常不適用於RAW圖像。(嗯,它是原始的。)儘管如此,RAW圖像包含一個JPEG預覽,相機已經對其應用校正。ImageMagick可以透過使用dcraw讀取RAW圖像。因此,可以將原始圖像轉換為沒有鏡頭校正的JPEG,並將結果與內部校正的JPEG縮略圖進行比較。在這種圖像對的情況下,可以直接計算校正參數。透過在兩個圖像中選擇對應的點對,我們可以直接建立r
和R
之間的關係。 ![[RAW 圖像]](raw_marks.jpg)
原始圖像(桶狀變形)
![[校正後的圖像]](thumb_marks.jpg)
校正後的縮略圖(用於反向工程)
r
和R
的對應值,然後計算迴歸曲線,例如透過試算表圖表。因此,ImageMagick命令列為
magick barrel.jpg -distort barrel '0.0099 -0.0678 0.0014 1.0511' flat.jpg |
barrel.dng
」。鏡頭校正範例
露營車
左側的露營車原始照片必須在黃昏時分從相當近的距離拍攝,因為攝影師背後有一個陡峭的斜坡,空間有限。(光線不足導致照片呈現藍色調,這是後期處理過程中嚴重增亮的結果。)原始照片顯示出明顯的桶狀變形,尤其是在圖像頂部附近的水平條紋和建築物的後角處。用於拍攝此照片的尼康Coolpix 995可以在PTlens的資料庫中找到,因此可以輕鬆校正變形,如中間所示。右側的圖像顯示了兩張照片灰階版本之間的差異,透過兩者相減、取反以及極端裁剪和伽瑪校正來計算。同樣,校正的效果最好透過頂部的水平條紋來說明。白色圓圈(表示零差異)是由於非縮放限制造成的:直徑等於圖像較小尺寸的圓上的點保持不變。GoPro 展平
GoPro相機鏡頭會產生明顯的桶狀變形,這似乎是其品牌的一部分。例如,GoPro Hero 3+銀色版配備了一個焦距為2.77毫米的魚眼鏡頭,如果使用整個感光區域,則相當於35毫米膠片中16毫米的焦距。GoPro Hero 3+有三種照片模式- 1000萬像素 = 3680 × 2760像素廣角(35毫米膠片中為16毫米)
- 700萬像素 = 3072 × 2304像素廣角(35毫米膠片中為16毫米)
- 500萬像素 = 2624 × 1968像素中焦(35毫米膠片中為23毫米)
- 廣角
- a = 0.06335
- b = -0.18432
- c = -0.13009
- 中焦
- a = 0.01359
- b = -0.06034
- c = -0.10618
ri
和 Ri
由比例因子 κ = 3680 / 2624 = 1.402 耦合,這導致- a2 = a1 / κ³
- b2 = b1 / κ²
- c2 = c1 / κ
- a = 0.030530
- b = -0.124312
- c = -0.038543
兩把鍵盤作者:el_supremo
我拍攝的兩把鍵盤的照片有非常明顯的桶形失真,因為它是在 17 毫米的焦距下拍攝的。這種失真可以使用例如 Canon 的 Digital Photo Professional 軟體進行校正(我有一台 Canon 50D 相機)。其他單眼相機製造商通常會提供軟體來對他們的鏡頭進行這種校正,但我想看看上面的例子在這張照片上的效果如何。第一步是訪問 LensFun 網站 並下載最新版本的相機資料庫。解壓縮套件(winzip 可以在 Windows 中解壓縮 .tar.gz 文件),然後在「lensfun/data/db
」目錄中查找與您的相機製造商對應的檔案。在我的例子中,我查看了「slr-canon.xml
」,它可以使用任何文字編輯器進行編輯。現在我找到了我正在使用的特定鏡頭的資訊,在我的例子中是「EF-S 17-85mm
」。該鏡頭的資訊如下所示
<lens> <maker>Canon</maker> <model>Canon EF-S 17-85mm f/4-5.6 IS USM</model> <mount>Canon EF-S</mount> <cropfactor>1.6</cropfactor> <calibration> <distortion model="ptlens" focal="17" a="0.021181" b="-0.055581" c="0" /> <distortion model="ptlens" focal="20" a="0.019344" b="-0.043786" c="0" /> <distortion model="ptlens" focal="22" a="0.015491" b="-0.026682" c="0" /> <distortion model="ptlens" focal="28" a="0.008084" b="-0.007472" c="0" /> <distortion model="ptlens" focal="30" a="0.005522" b="-0.001763" c="0" /> <distortion model="ptlens" focal="35" a="0.003149" b="0.002207" c="0" /> <distortion model="ptlens" focal="44" a="0" b="0.008269" c="0" /> <distortion model="ptlens" focal="53" a="0" b="0.008792" c="0" /> <distortion model="ptlens" focal="61" a="0" b="0.00738" c="0" /> <distortion model="ptlens" focal="72" a="0" b="0.006226" c="0" /> <distortion model="ptlens" focal="78" a="0" b="0.007095" c="0" /> <distortion model="ptlens" focal="85" a="0" b="0.007288" c="0" /> </calibration> </lens> |
a="0.021181" b="-0.055581" c="0"
這些是用於校正鏡頭失真的三個參數。但是,對於某些舊版本的 IM,桶形失真校正需要第四個參數 d。幸運的是,可以使用這個簡單的公式從其他三個參數輕鬆計算出 d 的值: d = 1-a-b-c
這意味著: d="1.0344"
。![]() ![]() |
如果沒有提供「d」作為變形參數,IM 會自動計算出「d」的值,但一些舊版本的 IM 不會這樣做。 |
![]() ![]() |
當然,在您完全完成影像處理之前,您不應該儲存為 JPEG 格式,因為 JPEG 會進行失真壓縮。 |