diff options
Diffstat (limited to 'meowpp.test/src/autostitch.cpp')
-rw-r--r-- | meowpp.test/src/autostitch.cpp | 384 |
1 files changed, 108 insertions, 276 deletions
diff --git a/meowpp.test/src/autostitch.cpp b/meowpp.test/src/autostitch.cpp index e63ef43..b62d13b 100644 --- a/meowpp.test/src/autostitch.cpp +++ b/meowpp.test/src/autostitch.cpp @@ -16,7 +16,6 @@ #include "meowpp/gra/Bitmap.h" #include "meowpp/gra/Photo.h" #include "meowpp/gra/Camera.h" -#include "meowpp/gra/WatchBall.h" #include "meowpp/math/utility.h" #include "meowpp/math/methods.h" @@ -43,6 +42,10 @@ double p0 = 0.07, P = 0.99; double q = 0.7, r = 0.01, Q = 0.97; double stop = 1; double o_radius = 500; +double angle_t = PI / 4.0; +double aspect_t = 2.0; + +std::vector<std::string> input_name; MyK_Match match; std::vector<Bitmap<RGBf_Space> > input_bitmap; @@ -73,54 +76,67 @@ std::vector<OutputSet> outputs; //////////////////////////// **# setup #** /////////////////////////// bool setup(int argc, char** argv) { - usg.optionAdd('h', "Display this help document."); - usg.optionAdd('i', + usg.optionAdd("h", "Display this help document."); + usg.optionAdd("i", "Specify the input images are in <type> " "instead of specifying from arguments", "<dirname>", "", false); - usg.optionAdd('o', + usg.optionAdd("o", "Output file name, (not include '.jpg' suffix)", "<filename>", "output", false); - usg.optionAdd('d', + usg.optionAdd("f", + "File name for output the text data", + "<filename>", + "output.txt", + false); + usg.optionAdd("d", "Specify which Feature-Point-Detect algorithm to use", "<algorithm>", "", true); - usg.optionAdd('p', + usg.optionAdd("ransac-p0", "Pribabilicity for RANSAC to choose a right feature point", "<floating point>", stringPrintf("%.10f", p0), false); - usg.optionAdd('P', + usg.optionAdd("ransac-ok", "Pribabilicity for RANSAC access", "<floating point>", stringPrintf("%.10f", P), false); - usg.optionAdd('q', + usg.optionAdd("prob-p1", "p1 for Prob. Model", "<floationg Point>", stringPrintf("%.10f", q), false); - usg.optionAdd('r', + usg.optionAdd("prob-p0", "p0 for Prob. Model", "<floationg Point>", stringPrintf("%.10f", r), false); - usg.optionAdd('Q', + usg.optionAdd("prob-min", "p_min for Prob. Model", "<floationg Point>", stringPrintf("%.10f", Q), false); - usg.optionAdd('s', + usg.optionAdd("s", "stop threshold for boundle adjustment", "<floationg Point>", stringPrintf("%.10f", stop), false); - usg.optionAdd('O', + usg.optionAdd("output-radius", "output ball radius", "<floationg Point>", stringPrintf("%.10f", o_radius), false); + usg.optionAdd("match-angle", + "angle threshold for matching", + "<floating point>", stringPrintf("%.10f", angle_t / PI * 180), + false); + usg.optionAdd("match-aspect", + "aspect threshold for matching", + "<floating point>", stringPrintf("%.10f", aspect_t), + false); std::vector<std::string> fpsd_algorithm_list = ObjSelector<FPSD_ID>::names(); for (size_t i = 0, I = fpsd_algorithm_list.size(); i < I; i++) { const ObjBase* tmp = ObjSelector<FPSD_ID>::get(fpsd_algorithm_list[i]); - usg.optionValueAcceptAdd('d', + usg.optionValueAcceptAdd("d", fpsd_algorithm_list[i], tmp->type()); usg.import(((MyFeaturePointsDetector*)tmp)->usage()); @@ -130,7 +146,7 @@ bool setup(int argc, char** argv) { // set arg std::string err_msg; bool ok = usg.arguments(argc, argv, &err_msg); - if (usg.hasOptionSetup('h')) { + if (usg.hasOptionSetup("h")) { printf("%s\n", usg.usage().c_str()); exit(0); } @@ -144,12 +160,11 @@ bool setup(int argc, char** argv) { //////////////// **# Input images and convert it #** ///////////////// bool input() { - std::vector<std::string> input_name; - if (!usg.hasOptionSetup('i')) { + if (!usg.hasOptionSetup("i")) { input_name = usg.procArgs(); } else { - std::string base = usg.optionValue('i', 0); + std::string base = usg.optionValue("i", 0); if (base.length() == 0 || base[base.length() - 1] != '/') { base += "/"; } @@ -197,7 +212,7 @@ bool input() { //////////////////////// **# FeaturePoint #** //////////////////////// bool detect() { - std::string fpsd_algo_name = usg.optionValue('d', 0); + std::string fpsd_algo_name = usg.optionValue("d", 0); MyFeaturePointsDetector* detector( (MyFeaturePointsDetector*)ObjSelector<FPSD_ID>::create(fpsd_algo_name)); detector->usage(usg); @@ -237,11 +252,11 @@ bool ransac() { messagePrintf( 1, "RANSAC"); MyRansacCheck::usage(usg); // tmp output - p0 = inRange(0.00001, 0.9999, atof(usg.optionValue('p', 0).c_str())); - P = inRange(0.00001, 0.9999, atof(usg.optionValue('P', 0).c_str())); + p0 = inRange(0.00001, 0.9999, atof(usg.optionValue("ransac-p0", 0).c_str())); + P = inRange(0.00001, 0.9999, atof(usg.optionValue("ransac-ok", 0).c_str())); for (size_t i = 0, I = input_bitmap.size(); i < I; i++) { for (size_t j = 0, J = input_bitmap.size(); j < J; j++) { - size_t num = 3u; + size_t num = 4u; // !!!!!!!!!!!!!!!!!!! messagePrintf( 1, "ransac %lu --- %lu", i, j); MyRansacCheck chk(&(fpsv[i]), &(fpsv[j])); FeaturePointIndexPairs ret = ransac(pairs[i][j], chk, num, p0, P); @@ -273,11 +288,13 @@ bool ransac() { return true; } -///////////////////////// **# prob module #** //////////////////////// -bool prob_mod() { - q = inRange(0.00001, 0.99999, atof(usg.optionValue('q', 0).c_str())); - r = inRange(0.00001, 0.99999, atof(usg.optionValue('r', 0).c_str())); - Q = inRange(0.00001, 0.99999, atof(usg.optionValue('Q', 0).c_str())); +//////////////////// **# checking match again #** //////////////////// +bool match_check() { + q = inRange(0.00001, 0.99999, atof(usg.optionValue("prob-p1", 0).c_str())); + r = inRange(0.00001, 0.99999, atof(usg.optionValue("prob-p0", 0).c_str())); + Q = inRange(0.00001, 0.99999, atof(usg.optionValue("prob-min", 0).c_str())); + aspect_t = inRange(0.000001, 9999.0, atof(usg.optionValue("match-aspect", 0).c_str())); + angle_t = inRange(0.1,999.0, atof(usg.optionValue("match-angle", 0).c_str()))/180 * PI; double m_ni = log(q * (1 - r)) - log(r * (1 - q)); double c = log(Q) - log(1 - Q); double m_nf = log(1 - r) - log(1 - q); @@ -291,150 +308,32 @@ bool prob_mod() { double ni = pairs[i][j].size(), nf = 0; MyRansacCheck chk(&(fpsv[i]), &(fpsv[j])); chk.rememberVCalc(pairs[i][j]); - for (size_t k = 0, K = fpsv[i].size(); k < K; k++) { - Vector2D<double> to(chk.to(Vector2D<double>(fpsv[i][k](0), - fpsv[i][k](1)))); - if (0 <= to.x() && to.x() <= (double)input_bitmap[j].width() && - 0 <= to.y() && to.y() <= (double)input_bitmap[j].height()) { - nf++; + if (chk.check(aspect_t, angle_t)) { + for (size_t k = 0, K = fpsv[i].size(); k < K; k++) { + Vector2D<double> to(chk.to(Vector2D<double>(fpsv[i][k](0), + fpsv[i][k](1)))); + if (0 <= to.x() && to.x() <= (double)input_bitmap[j].width() && + 0 <= to.y() && to.y() <= (double)input_bitmap[j].height()) { + nf++; + } } - } - if (ni * m_ni > c + m_nf * nf) { - messagePrintf(0, "accept %lu --- %lu", i, j); - messagePrintf(0, - "%.0f * %.3f = %.3f ?? %.3f = %.3f + %.3f * %.0f", - ni, m_ni, ni * m_ni, c + m_nf * nf, c, m_nf, nf); - continue; - } - else { - pairs[i][j].clear(); - } - } - } - messagePrintf(-1, "ok"); - return true; -} - -///////////////////// **# group them together #** //////////////////// -bool group() { - messagePrintf(1, "group"); - // union - DisjointSet dsj(input_bitmap.size()); - for (size_t i = 0, I = input_bitmap.size(); i < I; i++) { - for (size_t j = 0; j < I; j++) { - if(pairs[i][j].empty()) continue; - dsj.merge(i, j); - } - } - std::vector<size_t> root; - for (size_t i = 0, I = input_bitmap.size(); i < I; i++) { - if (dsj.root(i) == i) { - root.push_back(i); - } - } - // split into groups - outputs.resize(root.size()); - for (size_t i = 0, I = root.size(); i < I; i++) { - messagePrintf(1, "Group %d", i); - std::vector<size_t> ids; - for (size_t j = 0, J = input_bitmap.size(); j < J; j++) { - if (dsj.root(j) != root[i]) continue; - outputs[i].cameras.push_back(Camera<RGBf_Space>()); - outputs[i].cameras[outputs[i].cameras.size() - 1].photo( - Photo<RGBf_Space>(input_bitmap[j]) - ); - ids.push_back(j); - messagePrintf(0, "camera %lu from bitmap %lu", - outputs[i].cameras.size() - 1, j); - } - for (size_t j = 0, J = ids.size(); j < J; ++j) { - for (size_t k = 0; k < J; ++k) { - if (j == k) continue; - size_t i1 = ids[j], i2 = ids[k]; - if (pairs[i1][i2].empty()) continue; - outputs[i].edges.push_back(OutputSet::Edge(j, k)); - size_t index = outputs[i].edges.size() - 1; - for (size_t n = 0, N = pairs[i1][i2].size(); n < N; ++n) { - outputs[i].edges[index].v1.push_back( - fpsv[i1][pairs[i1][i2][n].from.second] - ); - outputs[i].edges[index].v2.push_back( - fpsv[i1][pairs[i1][i2][n].to.second] - ); + if (ni * m_ni > c + m_nf * nf) { + messagePrintf(0, "accept %lu --- %lu", i, j); + messagePrintf(0, + "%.0f * %.3f = %.3f ?? %.3f = %.3f + %.3f * %.0f", + ni, m_ni, ni * m_ni, c + m_nf * nf, c, m_nf, nf); + continue; } - messagePrintf(0, "Edge %lu---%lu, size = %lu", - i1, i2, outputs[i].edges[index].v1.size()); - } - } - std::sort(outputs[i].edges.begin(), outputs[i].edges.end()); - messagePrintf(-1, ""); - } - messagePrintf(-1, "ok"); - return true; -} - -////////////////////// **# boundle adjustment #** //////////////////// -bool boundle() { - stop = inRange(0.01, 100000.0, atof(usg.optionValue('s', 0).c_str())); - messagePrintf(1, "boundle adjustment"); - for (size_t i = 0, I = outputs.size(); i < I; i++) { - int id = 0; - std::set<size_t> in; - size_t i1 = outputs[i].edges[0].i1; - size_t i2 = outputs[i].edges[0].i2; - for (size_t j = 0, J = outputs[i].edges[0].v1.size(); j < J; ++j) { - outputs[i].cameras[i1].fixedPoints2DGet().identityPointAdd( - id, outputs[i].edges[0].v1[j]); - outputs[i].cameras[i2].fixedPoints2DGet().identityPointAdd( - id, outputs[i].edges[0].v2[j]); - id++; - } - in.insert(i1); - in.insert(i2); - double r_lst = Camera<RGBf_Space>::boundleAdjustment2D( - &(outputs[i].cameras), - stop - ); - for (size_t j = 1, J = outputs[i].edges.size(); j < J; ++j) { - size_t best; - for (best = 0; best < J; ++best) { - if (in.find(outputs[i].edges[best].i1) == in.end() && - in.find(outputs[i].edges[best].i2) == in.end()) continue; - break; - } - i1 = outputs[i].edges[best].i1; - i2 = outputs[i].edges[best].i2; - for (size_t j = 0, J = outputs[i].edges[best].v1.size(); j < J; ++j) { - outputs[i].cameras[i1].fixedPoints2DGet().identityPointAdd( - id, outputs[i].edges[best].v1[j]); - outputs[i].cameras[i2].fixedPoints2DGet().identityPointAdd( - id, outputs[i].edges[best].v2[j]); - id++; } - in.insert(i1); - in.insert(i2); - std::vector<Camera<RGBf_Space> > tmp(outputs[i].cameras); - double r = Camera<RGBf_Space>::boundleAdjustment2D(&tmp, stop); - if (r > r_lst * 1.5) continue; - outputs[i].cameras = tmp; + pairs[i][j].clear(); } } messagePrintf(-1, "ok"); return true; } -bool expand() { - o_radius = inRange(100.0, 1000000.0, atof(usg.optionValue('O', 0).c_str())); - output_bitmap.resize(outputs.size()); - for (size_t i = 0, I = outputs.size(); i < I; ++i) { - WatchBall<RGBf_Space> wb; - wb.cameras(outputs[i].cameras); - output_bitmap[i] = wb.expand(o_radius); - } - return true; -} - ////////////////////// **# Write to output file #** ////////////////// + bool output() { messagePrintf(1, "Write images"); for (size_t i = 0; i < output_bitmap.size(); i++) { @@ -450,7 +349,7 @@ bool output() { img.at<cv::Vec3b>(y, x)[2] = tmp.r(); } } - std::string output_name(usg.optionValue('o', 0) + std::string output_name(usg.optionValue("o", 0) + (output_bitmap.size() > 1 ? stringPrintf("%lu", i) : "") @@ -467,54 +366,6 @@ bool output() { return true; } -//* -bool tmp_output() { - output_bitmap = input_bitmap; - for (size_t i = 0, I = input_bitmap.size(); i < I; i++) { - for (size_t j = 0, J = fpsv[i].size(); j < J; j++) { - ssize_t x = fpsv[i][j](0); - ssize_t y = fpsv[i][j](1); - ssize_t dx[2] = {0, 1}, x0[2] = {0, -10}; - ssize_t dy[2] = {1, 0}, y0[2] = {-10, 0}; - for(size_t k = 0; k < 2; k++){ - for(size_t count = 0; count < 20; count++){ - ssize_t xx = x + dx[k] * count + x0[k]; - ssize_t yy = y + dy[k] * count + y0[k]; - if(0 <= xx && xx < (ssize_t)input_bitmap[i].width() && - 0 <= yy && yy < (ssize_t)input_bitmap[i].height()){ - output_bitmap[i].pixel(yy, xx, Vector3D<double>(1.0, 1.0, 0.0)); - } - } - } - } - } - return output(); -} -// */ - -/* -bool g_output(){ - output_bitmap.resize(input_bitmap.size() * 2); - for(size_t i = 0, I = input_bitmap.size(); i < I; i++){ - output_bitmap[i * 2 ] = input_bitmap[i]; - output_bitmap[i * 2 + 1] = input_bitmap[i]; - output_bitmap[i * 2 ].gradiancedX(3, 3); - output_bitmap[i * 2 + 1].gradiancedY(3, 3); - for(size_t x = 0, X = output_bitmap[i * 2].width(); x < X; x++){ - for(size_t y = 0, Y = output_bitmap[i * 2].height(); y < Y; y++){ - Vector3D<double> v; - v = output_bitmap[i * 2](y, x); - output_bitmap[i * 2](y, x) = Vector3D<double>(v.length() / sqrt(2.0)); - v = output_bitmap[i * 2 + 1](y, x); - output_bitmap[i * 2 + 1](y, x) = Vector3D<double>(v.length() / sqrt(2.0)); - } - } - } - return output(); -} - -// */ - bool pair_output(){ for(size_t i = 0, I = input_bitmap.size(); i < I; i++){ for(size_t j = 0, J = input_bitmap.size(); j < J; j++){ @@ -523,75 +374,33 @@ bool pair_output(){ chk.rememberVCalc(pairs[i][j]); size_t index = output_bitmap.size(); output_bitmap.push_back(input_bitmap[i]); - for(ssize_t x = 0, X = input_bitmap[i].width(); x < X; x++){ - for(ssize_t y = 0, Y = input_bitmap[i].height(); y < Y; y++){ + for(ssize_t x = 0, X = input_bitmap[i].width(); x < X; x++) { + for(ssize_t y = 0, Y = input_bitmap[i].height(); y < Y; y++) { Vector2D<double> to(chk.to(Vector2D<double>(x, y))); ssize_t x2 = to.x(), y2 = to.y(); - if(0 <= x2 && x2 <= (ssize_t)input_bitmap[j].width() && - 0 <= y2 && y2 <= (ssize_t)input_bitmap[j].height()){ + if (0 <= x2 && x2 <= (ssize_t)input_bitmap[j].width() && + 0 <= y2 && y2 <= (ssize_t)input_bitmap[j].height()) { output_bitmap[index].pixel(y, x, (input_bitmap[i].pixel(y, x) + input_bitmap[j].pixel(y2,x2)) / 2 ); } } } - } - } - return output(); -} -/* -bool pair_output2(){ - for(size_t i = 0, I = input_bitmap.size(); i < I; i++){ - for(size_t j = 0, J = input_bitmap.size(); j < J; j++){ - if((i + 1) % I != j && (j + 1) % J != i) continue; - messagePrintf(0, "%3lu--%3lu: %lu", i, j, pairs[i][j].size()); - if(pairs[i][j].empty()) continue; - MyRansacCheck chk(&(fpsv[i]), &(fpsv[j])); - chk.rememberVCalc(pairs[i][j]); - size_t index = output_bitmap.size(); - output_bitmap.push_back(input_bitmap[i]); - for(ssize_t x = 0, X = input_bitmap[i].width(); x < X; x++){ - for(ssize_t y = 0, Y = input_bitmap[i].height(); y < Y; y++){ - Vector2D<double> to(chk.to(Vector2D<double>(x, y))); - ssize_t x2 = to.x(), y2 = to.y(); - if(0 <= x2 && x2 <= (ssize_t)input_bitmap[j].width() && - 0 <= y2 && y2 <= (ssize_t)input_bitmap[j].height()){ - output_bitmap[index].pixel(y, x, (input_bitmap[i].pixel(y, x) + - input_bitmap[j].pixel(y2,x2)) / 2 - ); + for (size_t k = 0, K = pairs[i][j].size(); k < K; ++k) { + ssize_t x0 = fpsv[i][pairs[i][j][k].from.second](0); + ssize_t y0 = fpsv[i][pairs[i][j][k].from.second](1); + for (ssize_t d = -10; d <= 10; ++d) { + if (0 <= x0 + d && x0 + d < (ssize_t)input_bitmap[i].width() - 1) { + output_bitmap[index].pixel(y0, x0 + d, + RGBf_Space(Vector3D<double>( + 1.0, 1.0, 0.0 + ))); } - } - } - for(size_t k = 0, K = fpsv[i].size(); k < K; k++){ - ssize_t dy[2] = {0, 1}, dx[2] = {1, 0}; - ssize_t y0[2] = {0, -10}, x0[2] = {-10, 0}; - ssize_t x = fpsv[i][k](0), y = fpsv[i][k](1); - for(ssize_t m = 0; m < 2; m++){ - for(ssize_t n = 0; n < 20; n++){ - ssize_t xx = x + x0[m] + dx[m] * n; - ssize_t yy = y + y0[m] + dy[m] * n; - if(0 <= xx && xx <= (ssize_t)input_bitmap[j].width() && - 0 <= yy && yy <= (ssize_t)input_bitmap[j].height()){ - output_bitmap[index].pixel(yy, xx, - Vector3D<double>(1.0, 1.0, 0)); - } - } - } - } - for(size_t k = 0, K = pairs[i][j].size(); k < K; k++){ - ssize_t dy[2] = {0, 1}, dx[2] = {1, 0}; - ssize_t y0[2] = {0, -10}, x0[2] = {-10, 0}; - ssize_t x = fpsv[i][pairs[i][j][k].from.second](0); - ssize_t y = fpsv[i][pairs[i][j][k].from.second](1); - for(ssize_t m = 0; m < 2; m++){ - for(ssize_t n = 0; n < 20; n++){ - ssize_t xx = x + x0[m] + dx[m] * n; - ssize_t yy = y + y0[m] + dy[m] * n; - if(0 <= xx && xx <= (ssize_t)input_bitmap[j].width() && - 0 <= yy && yy <= (ssize_t)input_bitmap[j].height()){ - output_bitmap[index].pixel(yy, xx, - Vector3D<double>(1.0, 0.0, 0)); - } + if (0 <= y0 + d && y0 + d < (ssize_t)input_bitmap[i].height() - 1) { + output_bitmap[index].pixel(y0 + d, x0, + RGBf_Space(Vector3D<double>( + 1.0, 1.0, 0.0 + ))); } } } @@ -599,8 +408,34 @@ bool pair_output2(){ } return output(); } -// */ +bool text_output() { + std::string s = usg.optionValue("f", 0); + FILE* f = fopen(s.c_str(), "w"); + fprintf(f, "%lu\n", input_bitmap.size()); + for (size_t i = 0, I = input_bitmap.size(); i < I; ++i) { + fprintf(f, "%s\n", input_name[i].c_str()); + fprintf(f, "%lu %lu %lu ", + input_bitmap[i].height(), input_bitmap[i].width(), fpsv[i].size()); + for (size_t j = 0, J = fpsv[i].size(); j < J; ++j) { + fprintf(f, "%.10f %.10f ", fpsv[i][j](0), fpsv[i][j](1)); + } + fprintf(f, "\n"); + for (size_t j = 0; j < I; ++j) { + fprintf(f, "%lu ", pairs[i][j].size()); + for (size_t k = 0, K = pairs[i][j].size(); k < K; ++k) { + fprintf(f, "%lu %lu %lu %lu ", + pairs[i][j][k].from.first, + pairs[i][j][k].from.second, + pairs[i][j][k].to.first, + pairs[i][j][k].to.second); + } + fprintf(f, "\n"); + } + } + fclose(f); + return true; +} int main(int argc, char** argv){ setup(argc, argv); @@ -608,11 +443,8 @@ int main(int argc, char** argv){ detect(); kmatch(); ransac(); - prob_mod(); - group(); - pair_output(); return 0; - boundle(); - expand(); - output(); + match_check(); + pair_output(); + text_output(); return 0; } |