Created
September 18, 2012 13:49
-
-
Save kazuki-ma/3743208 to your computer and use it in GitHub Desktop.
Ransac -- RANdom SAmple Consensus
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include "stdafx.h" | |
namespace tetlist{ | |
template <typename DATATYPE, typename FIT_PARAM, typename ACCURANCY = float> | |
class ransac{ | |
public: | |
typedef std::vector<DATATYPE> DATAM; | |
typedef FIT_PARAM FIT_PARAM; | |
typedef void (fitting)( | |
const DATAM& datam, | |
const std::vector<size_t> index, | |
FIT_PARAM ¶m); | |
typedef ACCURANCY (distance)( | |
const DATATYPE& data, | |
const FIT_PARAM& param); | |
typedef struct{ | |
size_t inliner_count; | |
FIT_PARAM fit_parameter; | |
std::vector<size_t> inliner_indexes; | |
} Result; | |
// RANSAC を実行する | |
static Result execute(DATAM& datam, fitting* fitting_func, distance& distance_func, | |
const ACCURANCY distance_threshhold, const size_t fitting_data_num, const size_t iteration_max) | |
{ | |
// 条件を初期化する | |
Result current_of_the_art; | |
current_of_the_art.inliner_count = 0; | |
// イテレーション開始 | |
std::vector<size_t> target_idx; | |
target_idx.resize(fitting_data_num); | |
auto rand = random<size_t>(0, datam.size() - 1); | |
for (size_t i = 0; i < iteration_max; ++i) { | |
// サンプル抽出 | |
for (size_t n = 0; n < fitting_data_num; ++n) { | |
target_idx.at(n) = rand(); | |
} | |
// 関数フィッティング | |
FIT_PARAM param; | |
fitting_func(datam, target_idx, param); | |
// インライアカウント | |
size_t inliner = 0; | |
for (auto it = datam.begin(); it != datam.end(); ++it) { | |
const auto distance = distance_func(*it, param); | |
if (distance < distance_threshhold) { | |
++inliner; | |
} | |
} | |
// 今回条件の方がフィットしていたら,最善結果を更新する | |
if (inliner > current_of_the_art.inliner_count) { | |
current_of_the_art.inliner_count = inliner; | |
current_of_the_art.fit_parameter = param; | |
} | |
} | |
// 結果を返す前に,インライアのインデックスを求めておく | |
current_of_the_art.inliner_indexes.resize(0); | |
for (size_t i = 0; i < datam.size(); ++i) { | |
if (distance_func(datam[i], current_of_the_art.fit_parameter) < distance_threshhold) { | |
current_of_the_art.inliner_indexes.push_back(i); | |
} | |
} | |
// 結果を返す | |
return current_of_the_art; | |
} | |
private: | |
}; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment