這段代碼,用 src 和 ref_images 儲存 在 src重建和ref 重建中都存在的圖像。
重建類包含有關單個重模組化型的所有資訊。 它由映射和捆綁調整類使用,并且可以寫入磁盤和從磁盤讀取。重建類中的圖像類:
圖像類是儲存有關圖像的資訊的類。 圖像是在某個位置(參數化為姿勢)拍攝的一台相機的産物。 一個圖像可以與多個其他圖像共享一個相機,如果它的内在特性是相同的
for (size_t i = 0; i < common_image_ids.size(); ++i) {
src_images[i] = &src_reconstruction.Image(common_image_ids[i]);
ref_images[i] = &ref_reconstruction.Image(common_image_ids[i]);
}
然年調用 ransac 進行兩個子模型的對準
如下是Estimate的參數,可見其隻需要兩個 圖像清單(src_images 和 ref_images),傳回是一個Report(涵蓋了模型對其的結果資料和是否成功布爾判斷吧應該)
typename LORANSAC<Estimator, LocalEstimator, SupportMeasurer, Sampler>::Report
LORANSAC<Estimator, LocalEstimator, SupportMeasurer, Sampler>::Estimate(
const std::vector<typename Estimator::X_t>& X,
const std::vector<typename Estimator::Y_t>& Y) {
下面應該是一些準備工作,num_samples就是采樣數,程式中 采樣數=兩模型共有的圖檔數,比如共有 10張圖 那麼ransac就采樣10次,
ransac應該是估計出滿足這10張圖檔的一個模型
,嗯。
CHECK_EQ(X.size(), Y.size());
const size_t num_samples = X.size();
typename RANSAC<Estimator, SupportMeasurer, Sampler>::Report report;
report.success = false;
report.num_trials = 0;
if (num_samples < Estimator::kMinNumSamples) {
return report;
}
這邊是申請一些變量,變量的含義在注釋中
//最優的模型解
typename SupportMeasurer::Support best_support;
typename Estimator::M_t best_model;
bool best_model_is_local = false;
bool abort = false;
//最大的殘差
const double max_residual = options_.max_error * options_.max_error;
// 用于存儲每個 采樣點殘差 的數組
std::vector<double> residuals(num_samples);
//
std::vector<typename LocalEstimator::X_t> X_inlier;
std::vector<typename LocalEstimator::Y_t> Y_inlier;
// 臨時的全局 Estimator
std::vector<typename Estimator::X_t> X_rand(Estimator::kMinNumSamples);
std::vector<typename Estimator::Y_t> Y_rand(Estimator::kMinNumSamples);
// 采樣類的執行個體化,參數隻是一個采樣數
sampler.Initialize(num_samples);
// 确定采樣數
size_t max_num_trials = options_.max_num_trials;
max_num_trials = std::min<size_t>(max_num_trials, sampler.MaxNumSamples());
size_t dyn_max_num_trials = max_num_trials;
假如說num_trials為100,意思是進行100輪的ransac估計,下面就是for循環
for (report.num_trials = 0; report.num_trials < max_num_trials;
++report.num_trials) {
// 暫停,跳過一次循環
if (abort) {
report.num_trials += 1;
break;
}
// 進行采樣,以common images數量為10為例,這裡随機采樣10個圖檔吧應該
sampler.SampleXY(X, Y, &X_rand, &Y_rand);
// 用采樣到的這10張圖檔,估計模型,怎麼估計的,估計的細節是什麼在下一個部落格
// 傳回不止一個模型,傳回一個模型集合 sample_models
const std::vector<typename Estimator::M_t> sample_models =
estimator.Estimate(X_rand, Y_rand);
// 循環選擇出最好的
for (const auto& sample_model : sample_models) {
// 用模型估計殘差,怎麼估計,估計的細節在下一個部落格
estimator.Residuals(X, Y, sample_model, &residuals);
CHECK_EQ(residuals.size(), X.size());
const auto support = support_measurer.Evaluate(residuals, max_residual);
// Do local optimization if better than all previous subsets.
if (support_measurer.Compare(support, best_support)) {
//如果目前的模型最優 ↓↓↓↓
best_support = support;
best_model = sample_model;
best_model_is_local = false;
// Estimate locally optimized model from inliers.
// Estimator 和 LocalEstimator 應該分别指的是全局的ransac估計和
// 這10個采樣的ransac估計?
if (support.num_inliers > Estimator::kMinNumSamples &&
support.num_inliers >= LocalEstimator::kMinNumSamples) {
X_inlier.clear();
Y_inlier.clear();
X_inlier.reserve(support.num_inliers);
Y_inlier.reserve(support.num_inliers);
// ransac的政策,如果遇到更好的,就用目前的10張圖檔為基礎,
// 在這10個的基礎上進行估計
// X_inlier 和 Y_inlier 是更好的采樣資料
// 通過計算内點的數量并對所有内點殘差求和來衡量模型的支援度。
// 如果它具有更多的内點和更小的殘差總和,則此模型為更好
for (size_t i = 0; i < residuals.size(); ++i) {
if (residuals[i] <= max_residual) {
X_inlier.push_back(X[i]);
Y_inlier.push_back(Y[i]);
}
}
const std::vector<typename LocalEstimator::78h> local_models =
local_estimator.Estimate(X_inlier, Y_inlier);
//在更好的采樣結果上重複篩選操作
for (const auto& local_model : local_models) {
local_estimator.Residuals(X, Y, local_model, &residuals);
CHECK_EQ(residuals.size(), X.size());
const auto local_support =
support_measurer.Evaluate(residuals, max_residual);
// 儲存最好的結果
if (support_measurer.Compare(local_support, best_support)) {
best_support = local_support;
best_model = local_model;
best_model_is_local = true;
}
}
}
// 調整一下循環次數,優化時間
dyn_max_num_trials =
RANSAC<Estimator, SupportMeasurer, Sampler>::ComputeNumTrials(
best_support.num_inliers, num_samples, options_.confidence,
options_.dyn_num_trials_multiplier);
}
// 特判跳出循環
if (report.num_trials >= dyn_max_num_trials &&
report.num_trials >= options_.min_num_trials) {
abort = true;
break;
}
}
}