簡體   English   中英

如何使用opencv bundle調整

[英]How to use opencv bundle adjustment

我已經計算了5個相機矩陣( c1, ... c5 ),通過將3D物體放置在5個不同的位置來計算相機矩陣,並且對於每個位置我已經計算出相機矩陣(並且相機是恆定的)。 相機矩陣使用SVD方法計算。

現在我想在opencv使用bundle調整來獲得一個最佳的相機矩陣。 我在這里找到了文檔

但文檔不清楚,我也無法找到任何示例代碼。 任何人都可以解釋我如何使用opencv bundle調整來獲得optimal camera matrix

請參閱使用OpenCV學習圖像處理的第155頁的示例代碼。 像這樣的東西:

vector<CameraParams> cameras;
vector<MatchesInfo> pairwise_matches;
vector<ImageFeatures> features(num_images);

// initialize the above params here

Ptr<BundleAdjusterBase> adjuster;
adjuster = makePtr<BundleAdjusterReproj>();
if (!(*adjuster)(features, pairwise_matches, cameras)) {
    cout << "Camera parameters adjusting failed." << endl; 
    return -1;
}

如果您提供MCVE,那么它會更容易提供幫助。

編輯:鑒於您有5個相同K矩陣的估計值。 最簡單的方法是簡單地平均您的5個估計值以獲得更准確的K.在一些溫和的假設下,這將是一個最佳估計。 如果重投影錯誤差異很大,那么您可以計算加權平均值。

我的回答是假設你使用一個特定的三維物體,其尺寸已經准確知道,從物體的多個圖像估計一個攝像機的內在參數。 根據你對@fireant的回答的評論,我認為這適用於你的問題。

關於'相機矩陣'含義的快速說明

術語“相機矩陣”非常模糊,可以通過多種方式理解:

  • 相機姿勢T = [R | t],也表示外部相機參數。
  • 內在相機矩陣K = [fx,s,cx; 0,fy,cy; 0,0,1]。
  • 相機投影矩陣P = K. [R | t]。

正如你所說,你有多個圖像,但你想要一個相機矩陣,我認為你在談論內在的相機矩陣K.

為什么你不應該使用捆綁調整

捆綁調整是一種用於解決比攝像機校准更普遍的問題的技術,其中外部攝像機參數(即3D方向和位置)和3D地標(例如3D點)都是未知的。 正如@fireant所指出的,在全局聯合優化中也可以包含內在的相機參數。 另一方面,相機校准假設3D地標是已知的並且由多個圖像中的單個相機觀察,因此它針對每個圖像優化了一組固有相機參數和一個相機姿勢。

要理解的是,更一般的優化問題涉及更多要優化的變量,因此更難以使它們受到良好約束。 如果它們沒有很好的約束,它們將以確實減少全局誤差的方式優化變量,但這並不符合您真正問題的解決方案。 這就是為什么在使用聯合優化算法時,您應該總是嘗試減少要優化的變量數量。

在捆綁調整VS攝像機校准的情況下,如果您不准確了解 3D地標的位置,則應該僅使用捆綁調整。 即便如此,嘗試解耦問題可能是更好的主意,例如事先校准3D對象。 如果您對3D地標的位置有准確的了解,那么它們不應被視為要優化的變量,因此您應該使用相機校准技術。

優化的初步估計

您說您對相機矩陣K有多個不准確的估計值,並且想要執行聯合優化以獲得單個更准確的估計。 問題在於,由於您想要估計單個攝像機矩陣,因此需要為聯合優化算法提供一個初始估計

為了仍然使用多個近似估計,您可以做的是嘗試選擇最接近真實解決方案的優化算法的初始估計。 為此,您可以使用多個啟發式標准。 例如,您可以選擇與最小重投影誤差相關聯的那個,或者您可以使用與校准對象最大的圖像相關聯的那個,等等。

但是,它可能不會對相機矩陣的最終估計產生很大的影響。

如何使用'calibrateCamera'完成此任務

假設您有一個帶有特征點的校准對象。 它可以是標准的2D棋盤或不對稱圓網格,或任何校准的3D對象。 並且假設您已經開發出一種在圖像中檢測此校准對象的方法(例如,自定義特征檢測器或手動確定對象位置的工具)。 然后,您可以定義一個矢量allObjectPoints ,其中包含可以檢測到的對象上的3D點。 然后,對於每個圖像i ,您可以確定檢測到的2D點的矢量imagePoints_i是對某些對象的3D點的觀察(注意,一些對象點可能被遮擋,因此可能存在比在allObjectPoints更少的項目)。 然后,由於所有對象點都是可識別的(直接或通過推理),您可以確定向量objectPoints_i ,其中包含在圖像i實際觀察到的對象3D點並與imagePoints_i一致地進行imagePoints_i

然后將所有objectPoints_i向量堆疊在向量objectPoints一個大向量中。 類似地,您將所有imagePoints_i向量堆疊在一個矢量imagePoints大向量中。 然后,您可以使用標志CV_CALIB_USE_INTRINSIC_GUESS調用calibrateCamera ,以指示您希望優化算法使用您提供的初始值。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM