diff options
Diffstat (limited to 'meowpp.test/src')
-rw-r--r-- | meowpp.test/src/autostitch.cpp | 384 | ||||
-rw-r--r-- | meowpp.test/src/autostitch_FeaturePointsDetector_Harris.cpp | 28 | ||||
-rw-r--r-- | meowpp.test/src/autostitch_K_Match.cpp | 4 | ||||
-rw-r--r-- | meowpp.test/src/autostitch_RansacCheck.cpp | 103 | ||||
-rw-r--r-- | meowpp.test/src/dsa.cpp | 15 | ||||
-rw-r--r-- | meowpp.test/src/oo.cpp | 32 | ||||
-rw-r--r-- | meowpp.test/src/rot_bundle.cpp | 319 |
7 files changed, 534 insertions, 351 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; } diff --git a/meowpp.test/src/autostitch_FeaturePointsDetector_Harris.cpp b/meowpp.test/src/autostitch_FeaturePointsDetector_Harris.cpp index ebcca5b..573c4b6 100644 --- a/meowpp.test/src/autostitch_FeaturePointsDetector_Harris.cpp +++ b/meowpp.test/src/autostitch_FeaturePointsDetector_Harris.cpp @@ -13,45 +13,45 @@ class Harris: public MyFeaturePointsDetector{ public: Usage usage() const{ Usage ret; - ret.optionAdd('K', + ret.optionAdd("harris-k", "Specify the constant K of 'R = detM - KtraceM'", "<floating point>", stringPrintf("%.10f", _body.paramK()), false); - ret.optionAdd('R', + ret.optionAdd("harris-r", "Specify the threshold of R to determind whether is " "featuer point or not", "<floating point>", stringPrintf("%.10f", _body.paramR()), false); - ret.optionAdd('W', + ret.optionAdd("harris-w", "Specify the sigma of the gaussian blur", "<floating point>", stringPrintf("%.10f", _body.paramW()), false); - ret.optionAdd('N', + ret.optionAdd("harris-n", "Specify the sigma of the gaussian blur to de-noise", "<floating point>", stringPrintf("%.10f", _body.paramN()), false); - ret.optionAdd('G', + ret.optionAdd("harris-g", "Specify the sigma of the gaussian blur to generate feature", "<floating point>", stringPrintf("%.10f", _body.paramG()), false); - ret.optionAdd('L', + ret.optionAdd("harris-l", ".........", "<floating point>", stringPrintf("%.10f", _body.paramL()), false); - ret.optionAdd('B', + ret.optionAdd("harris-b", "Description size", "<number>", stringPrintf("%lu", _body.paramB()), false); return ret; } bool usage(meow::Usage const& usg){ - double K = atof(usg.optionValue('K', 0).c_str()); - double R = atof(usg.optionValue('R', 0).c_str()); - double W = atof(usg.optionValue('W', 0).c_str()); - double N = atof(usg.optionValue('N', 0).c_str()); - double L = atof(usg.optionValue('L', 0).c_str()); - double G = atof(usg.optionValue('G', 0).c_str()); - size_t B = atoi(usg.optionValue('B', 0).c_str()); + double K = atof(usg.optionValue("harris-k", 0).c_str()); + double R = atof(usg.optionValue("harris-r", 0).c_str()); + double W = atof(usg.optionValue("harris-w", 0).c_str()); + double N = atof(usg.optionValue("harris-n", 0).c_str()); + double L = atof(usg.optionValue("harris-l", 0).c_str()); + double G = atof(usg.optionValue("harris-g", 0).c_str()); + size_t B = atoi(usg.optionValue("harris-b", 0).c_str()); _body.paramK(K); _body.paramR(R); _body.paramW(W); diff --git a/meowpp.test/src/autostitch_K_Match.cpp b/meowpp.test/src/autostitch_K_Match.cpp index d2fe8c6..6e5c69f 100644 --- a/meowpp.test/src/autostitch_K_Match.cpp +++ b/meowpp.test/src/autostitch_K_Match.cpp @@ -18,7 +18,7 @@ MyK_Match::~MyK_Match(){ Usage MyK_Match::usage() const{ Usage usg; - usg.optionAdd('k', + usg.optionAdd("kmatch-k", "k nearest neighbors", "<number>", stringPrintf("%d", 5), false); @@ -26,7 +26,7 @@ Usage MyK_Match::usage() const{ } bool MyK_Match::usage(meow::Usage const& usg){ - _body.paramK(atoi(usg.optionValue('k', 0).c_str())); + _body.paramK(atoi(usg.optionValue("kmatch-k", 0).c_str())); return true; } diff --git a/meowpp.test/src/autostitch_RansacCheck.cpp b/meowpp.test/src/autostitch_RansacCheck.cpp index 0410396..becc7da 100644 --- a/meowpp.test/src/autostitch_RansacCheck.cpp +++ b/meowpp.test/src/autostitch_RansacCheck.cpp @@ -3,27 +3,30 @@ #include "meowpp/math/Matrix.h" #include "meowpp/math/Vector.h" #include <utility> +#include <cmath> +#include <algorithm> + using namespace meow; double MyRansacCheck::threshold = 5.0; -meow::Usage MyRansacCheck::usage(){ +meow::Usage MyRansacCheck::usage() { Usage usg; - usg.optionAdd('t', + usg.optionAdd("ransac-threshold", "Threshold for RANSAC", "<floating point>", stringPrintf("%.10f", threshold), false); return usg; } -bool MyRansacCheck::usage(Usage const& usg){ +bool MyRansacCheck::usage(Usage const& usg) { threshold = inRange(0.0000001, 1000.0, - atof(usg.optionValue('t', 0).c_str())); + atof(usg.optionValue("ransac-threshold", 0).c_str())); return true; } -MyRansacCheck::MyRansacCheck(){ +MyRansacCheck::MyRansacCheck() { } @@ -44,44 +47,58 @@ MyRansacCheck::~MyRansacCheck(){ } -std::pair<Vector3D<double>, Vector3D<double> > MyRansacCheck::vCalc( - std::vector<FeaturePointIndexPair> const& __sample -) const{ - Matrix<double> m(6, 7, 0.0); - for(size_t i = 0; i < 3u; i++){ +Vector<double> MyRansacCheck::vCalc(std::vector<FeaturePointIndexPair> const& __sample) const { + Matrix<double> m(__sample.size() * 2, 9, 0.0); + for (size_t i = 0, I = __sample.size(); i < I; ++i) { m(i * 2 , 0, (*_from)[__sample[i].from.second](0)); m(i * 2 , 1, (*_from)[__sample[i].from.second](1)); m(i * 2 , 2, 1.0); - m(i * 2 , 6, (*_to)[__sample[i].to.second](0)); + m(i * 2 , 6, -(*_from)[__sample[i].from.second](0) * (*_to)[__sample[i].to.second](0)); + m(i * 2 , 7, -(*_from)[__sample[i].from.second](1) * (*_to)[__sample[i].to.second](0)); + m(i * 2 , 8, (*_to)[__sample[i].to.second](0)); m(i * 2 + 1, 3, (*_from)[__sample[i].from.second](0)); m(i * 2 + 1, 4, (*_from)[__sample[i].from.second](1)); m(i * 2 + 1, 5, 1.0); - m(i * 2 + 1, 6, (*_to)[__sample[i].to.second](1)); + m(i * 2 + 1, 6, -(*_from)[__sample[i].from.second](0) * (*_to)[__sample[i].to.second](1)); + m(i * 2 + 1, 7, -(*_from)[__sample[i].from.second](1) * (*_to)[__sample[i].to.second](1)); + m(i * 2 + 1, 8, (*_to)[__sample[i].to.second](1)); } - m.triangulared(); - Vector<double> x(6, 0.0); - for(ssize_t i = 5; i >= 0; i--){ - double sum = 0; - for(size_t j = i + 1; j < 6u; j++){ - sum += x(j) * m(i, j); + if (__sample.size() == 4) { + m.triangulared(); + Vector<double> x(8, 0.0); + for (ssize_t i = 7; i >= 0; i--) { + double sum = 0; + for (size_t j = i + 1; j < 8u; j++) { + sum += x(j) * m(i, j); + } + x.entry(i, (m(i, 8) - sum) / m(i, i)); } - x.entry(i, (m(i, 6) - sum) / m(i, i)); + return x; + } + else { + Matrix<double> b(m.col(8)); + m.cols(8, 0.0); + Vector<double> v((m.transpose() * m).inverse() * m.transpose() * b); + return v; } - Vector3D<double> vX(x(0), x(1), x(2)); - Vector3D<double> vY(x(3), x(4), x(5)); - return std::pair<Vector3D<double>, Vector3D<double> >(vX, vY); } void MyRansacCheck::rememberVCalc(std::vector<FeaturePointIndexPair> - const& __sample){ - std::pair<Vector3D<double>, Vector3D<double> > p(vCalc(__sample)); - _vX = p.first; - _vY = p.second; + const& __sample) { + Vector<double> x(vCalc(__sample)); + a_ = x(0); + b_ = x(1); + c_ = x(2); + d_ = x(3); + e_ = x(4); + f_ = x(5); + A_ = x(6); + B_ = x(7); } -bool MyRansacCheck::ok(FeaturePointIndexPair const& __m) const{ +bool MyRansacCheck::ok(FeaturePointIndexPair const& __m) const { Vector2D<double> from( (*_from)[__m.from.second](0), (*_from)[__m.from.second](1)); @@ -96,9 +113,9 @@ bool MyRansacCheck::ok(FeaturePointIndexPair const& __m) const{ double MyRansacCheck::operator()(std::vector<FeaturePointIndexPair> const& __sample, std::vector<FeaturePointIndexPair> - const& __data) const{ - for(size_t i = 0, I = __sample.size(); i < I; i++){ - for(size_t j = 0, J = __sample.size(); j < J; j++){ + const& __data) const { + for(size_t i = 0, I = __sample.size(); i < I; i++) { + for (size_t j = 0, J = __sample.size(); j < J; j++) { if(i == j) continue; if(__sample[i].from.second == __sample[j].from.second) return -1; if(__sample[i].to .second == __sample[j].to .second) return -1; @@ -106,16 +123,32 @@ double MyRansacCheck::operator()(std::vector<FeaturePointIndexPair> } ((MyRansacCheck*)this)->rememberVCalc(__sample); size_t ret = 0; - for(size_t i = 0, I = __data.size(); i < I; i++){ - if(ok(__data[i])){ + for (size_t i = 0, I = __data.size(); i < I; i++) { + if (ok(__data[i])) { ret++; } } return 0.001 + ret; } +bool MyRansacCheck::check(double r, double a) { + return true; + Vector2D<double> v_x(a_, b_); + Vector2D<double> v_y(c_, d_); + double len1 = v_x.length() * r; + double len2 = v_x.length() / r; + double len = v_y.length(); + if (len1 > len2) std::swap(len1, len2); + if (len < len1 || len2 < len) return false; + double sn = fabs(sin(a)); + double msn = fabs(v_x.cross(v_y) / v_x.length() / v_y.length()); + if (msn < sn) return false; + return true; +} -Vector2D<double> MyRansacCheck::to(Vector2D<double> const& __v) const{ - Vector3D<double> v(__v(0), __v(1), 1); - return Vector2D<double>(v.dot(_vX), v.dot(_vY)); +Vector2D<double> MyRansacCheck::to(Vector2D<double> const& v) const { + return Vector2D<double>( + (v.x() * a_ + v.y() * b_ + c_) / (A_ * v.x() + B_ * v.y() + 1), + (v.x() * d_ + v.y() * e_ + f_) / (A_ * v.x() + B_ * v.y() + 1) + ); } diff --git a/meowpp.test/src/dsa.cpp b/meowpp.test/src/dsa.cpp index 9b93395..8a3c499 100644 --- a/meowpp.test/src/dsa.cpp +++ b/meowpp.test/src/dsa.cpp @@ -14,15 +14,16 @@ int count = 0; int main(int argc, char** argv){ std::vector<std::string> ids(meow::ObjSelector<0>::names()); - usg2.optionAdd('t', "Select which subject to test", + usg2.optionAdd("t", "Select which subject to test", "<number>", "", false); for(size_t i = 0; i < ids.size(); i++){ TestFunction* tmp = (TestFunction*)meow::ObjSelector<0>::get(ids[i]); - usg2.optionValueAcceptAdd('t', ids[i], tmp->name() + ", " + tmp->description()); + usg2.optionValueAcceptAdd("t", ids[i], tmp->name()+", "+tmp->description()); } - usg.optionAdd('h', "Display this help document"); + usg.optionAdd("h", "Display this help document"); + usg.optionAdd("help", "Display this help document"); usg.usageBeginAdd("<name> is a little test program to check whether" "the data structures in the template is correct by" "random generate lots of data to test"); @@ -33,14 +34,14 @@ int main(int argc, char** argv){ if(usg.arguments(argc, argv, &err) == false){ printf("%s\n\n%s\n", err.c_str(), usg.usage().c_str()); return 1; - }else if(usg.hasOptionSetup('h')){ + }else if(usg.hasOptionSetup("h") || usg.hasOptionSetup("help")) { printf("%s", usg.usage().c_str()); return 0; }else{ usg2.update(usg); - if(usg2.optionValuesSize('t') > 0){ - for(int i = 0, I = usg2.optionValuesSize('t'); i < I; i++){ - std::string wh = usg2.optionValue('t', i); + if(usg2.optionValuesSize("t") > 0){ + for(int i = 0, I = usg2.optionValuesSize("t"); i < I; i++){ + std::string wh = usg2.optionValue("t", i); TestFunction* f = (TestFunction*)meow::ObjSelector<0>::get(wh); if(f->run() == false){ printf("error occure on %s\n", f->name().c_str()); diff --git a/meowpp.test/src/oo.cpp b/meowpp.test/src/oo.cpp index 54c69d5..ede8a24 100644 --- a/meowpp.test/src/oo.cpp +++ b/meowpp.test/src/oo.cpp @@ -6,6 +6,7 @@ #include <algorithm> #include <ctime> +#include <cmath> using namespace meow; @@ -14,13 +15,14 @@ private: struct Myself{ int n; Myself() { } + Myself(Myself const& m): n(m.n) { + } ~Myself() { } - void copyFrom(Myself const& m){ n = m.n; } }; Self<Myself> const self; public: - A(): self(true){ self()->n = 0; } - A(A const& b): self(false) { copyFrom(b); } + A(): self(){ self()->n = 0; } + A(A const& b): self(b.self, Self<Myself>::COPY_FROM) { } ~A() { } int num() const { return self->n; } int num(int k) { return (self()->n = k); } @@ -34,38 +36,33 @@ struct B { B() { n = 0; count = 1; } }; -static A as[100]; -static B *bs[100]; - -static size_t N = 100; +static const size_t N = 50; +static A as[N]; +static B *bs[N]; int main(){ + srand(time(0)); for (size_t i = 0; i < N; i++) { bs[i] = new B; } - for (size_t i = 0; i < 1000; i++) { + for (size_t i = 0; i < 500; i++) { int k = rand(); - if (k % 3 == 0) { + if (k % 3 == 0) { // copyFrom int x, y; do { x = rand() % N; y = rand() % N; } while(x == y); as[x].copyFrom(as[y]); - bs[x]->count--; - if (bs[x]->count == 0) { - delete bs[x]; - } - bs[x] = new B; bs[x]->n = bs[y]->n; } - else if (k % 3 == 1) { + else if (k % 3 == 1) { // referenceFrom int x, y; do { x = rand() % N; y = rand() % N; - } while(x == y); + } while(x == y || x / (N / 5) != y / (N / 5)); as[x].referenceFrom(as[y]); bs[x]->count--; if (bs[x]->count == 0) { @@ -74,7 +71,7 @@ int main(){ bs[x] = bs[y]; bs[x]->count++; } - else { + else { // set value int x = rand() % N, v = rand() % 100; as[x].num(v); bs[x]->n = v; @@ -90,6 +87,7 @@ int main(){ printf("false!\n"); return 1; } + //for (size_t j = 0; j < N; j++) { printf("%d ", as[j].num()); } printf("\n"); } for (size_t i = 0; i < N; i++) { printf("%d ", as[i].num()); } printf("\n"); diff --git a/meowpp.test/src/rot_bundle.cpp b/meowpp.test/src/rot_bundle.cpp new file mode 100644 index 0000000..d626e8e --- /dev/null +++ b/meowpp.test/src/rot_bundle.cpp @@ -0,0 +1,319 @@ +#include <cstdio> +#include <string> +#include <cstdlib> +#include <algorithm> +#include <vector> + +#include <opencv/cv.h> +#include <opencv/highgui.h> + +#include "meowpp/dsa/DisjointSet.h" +#include "meowpp/Usage.h" +#include "meowpp/gra/Eye.h" +#include "meowpp/colors/RGB_Space.h" +#include "meowpp/gra/Bitmap.h" +#include "meowpp/utility.h" +#include "meowpp/math/utility.h" +#include "meowpp/geo/Vectors.h" +#include "meowpp/gra/WatchBall.h" + +#include "meowpp/gra/BundleAdjustment_LM.h" + +using namespace meow; + +////////////////////////////////////////////////////////////////// + +Usage usg("rot_bundle"); + +std::vector<std::string> bitmap_name; +std::vector<Eye<RGBf_Space> > eyes; +std::vector<std::vector<Vector<double> > > fpsv; +std::vector<std::vector<std::vector<PairToPair<size_t> > > > pairs; +std::vector<std::vector<size_t > > groups; +std::vector<WatchBall<RGBf_Space> > balls; +std::vector<Vector2D<double> > center; + +double f_init; +double threshold; + +////////////////////////////////////////////////////////////////// + +bool setup(int argc, char** argv) { + usg.optionAdd("f", + "Input text file", + "filename", + "", + true); + usg.optionAdd("h", + "help docu"); + usg.optionAdd("output-radius", + "...", + "floating point", + "1000", + false); + usg.optionAdd("o", + "prefix of output images", + "pathname", + "output", + false); + usg.optionAdd("f-init", + "init focal length", + "floating point", + "300.0", + false); + usg.optionAdd("t", + "threshold for bundle adjustment", + "floating point", + "5.0", + false); + std::string s; + bool ok = usg.arguments(argc, argv, &s); + if (usg.hasOptionSetup("h")) { + printf("%s\n", usg.usage().c_str()); + exit(0); + } + if (!ok) { + fprintf(stderr, "%s\n", s.c_str()); + exit(1); + } + return true; +} + +bool read() { + messagePrintf(1, "read file"); + FILE* f = fopen(usg.optionValue("f", 0).c_str(), "r"); + size_t N; + if (fscanf(f, "%lu", &N) < 1) { + fprintf(stderr, "format error!\n"); + exit(-1); + } + std::vector<std::vector<int> > fps_id; + int id_max = 0; + bitmap_name.resize(N); + eyes.resize(N); + fpsv.resize(N); + fps_id.resize(N); + pairs.resize(N); + center.resize(N); + for (size_t i = 0; i < N; ++i) { + pairs[i].resize(N); + char s[1000]; + if (fscanf(f, "%s", s) < 1) { + fprintf(stderr, "format error!\n"); + exit(-1); + } + size_t h, w; + if (fscanf(f, "%lu %lu", &h, &w) < 2) { + fprintf(stderr, "format error!\n"); + exit(-1); + } + center[i].y(1.0 * h / 2); + center[i].x(1.0 * w / 2); + bitmap_name[i] = s; + size_t M; + if (fscanf(f, "%lu", &M) < 1) { + fprintf(stderr, "format error!\n"); + exit(-1); + } + Vector<double> v(2, 0.0); + for (size_t j = 0; j < M; ++j) { + double x, y; + if (fscanf(f, "%lf %lf", &x, &y) < 2) { + fprintf(stderr, "format error!\n"); + exit(-1); + } + v.entry(0, x - center[i].x()); + v.entry(1, -(y - center[i].y())); + fpsv[i].push_back(v); + fps_id[i].push_back(id_max++); + } + for (size_t j = 0; j < N; ++j) { + size_t O; + if (fscanf(f, "%lu", &O) < 1) { + fprintf(stderr, "format error!\n"); + exit(-1); + } + for (size_t k = 0; k < O; ++k) { + size_t a, b, c, d; + if (fscanf(f, "%lu %lu %lu %lu", &a, &b, &c, &d) < 4) { + fprintf(stderr, "format error!\n"); + exit(-1); + } + pairs[i][j].push_back(PairToPair<size_t>(a, b, c, d)); + } + } + } + fclose(f); + messagePrintf(-1, "ok"); + messagePrintf(1, "merge fixed points"); + DisjointSet st(id_max); + for (size_t i = 0, I = eyes.size(); i < I; ++i) { + for (size_t j = 0, J = pairs[i].size(); j < J; ++j) { + for (size_t k = 0, K = pairs[i][j].size(); k < K; ++k) { + st.merge(fps_id[pairs[i][j][k].from.first][pairs[i][j][k].from.second], + fps_id[pairs[i][j][k].to .first][pairs[i][j][k].to .second]); + } + } + } + for (size_t i = 0, I = eyes.size(); i < I; ++i) { + std::string s(stringPrintf("eye %lu: ", i)); + for (size_t j = 0, J = fps_id[i].size(); j < J; ++j) { + int id = st.root(fps_id[i][j]); + s += stringPrintf("%d ", id); + eyes[i].cameraGet().fixedPoints2DGet().identityPointAdd(id, fpsv[i][j]); + } + messagePrintf(0, "%s", s.c_str()); + } + messagePrintf(-1, "ok"); + messagePrintf(0, "Number of Eyes: %lu", eyes.size()); + for (size_t i = 0, I = eyes.size(); i < I; ++i) { + messagePrintf(0, "eyes[%lu] have %lu fixed points", i, fpsv[i].size()); + } + messagePrintf(0, "relation:"); + for (size_t i = 0, I = eyes.size(); i < I; ++i) { + std::string s; + for (size_t j = 0; j < I; ++j) { + s += stringPrintf("%3lu ", pairs[i][j].size()); + } + messagePrintf(0, "%s", s.c_str()); + } + return true; +} + +bool group() { + size_t N = eyes.size(); + messagePrintf(1, "group"); + // union + DisjointSet dsj(N); + for (size_t i = 0; i < N; i++) { + for (size_t j = 0; j < N; j++) { + if(pairs[i][j].empty()) continue; + dsj.merge(i, j); + } + } + std::vector<size_t> root; + for (size_t i = 0, I = eyes.size(); i < I; i++) { + if (dsj.root(i) == i) { + root.push_back(i); + } + } + // split into groups + groups.resize(root.size()); + for (size_t i = 0, I = root.size(); i < I; i++) { + messagePrintf(1, "Group %lu", i); + std::vector<size_t> ids; + for (size_t j = 0; j < N; ++j) { + if (dsj.root(j) != root[i]) continue; + groups[i].push_back(j); + } + for (size_t j = 0, J = groups[i].size(); j < J; ++j) { + messagePrintf(0, "eye %lu", groups[i][j]); + } + messagePrintf(-1, ""); + } + messagePrintf(-1, "ok"); + return true; +} + +bool bundle() { + threshold = inRange(0.0005, 1000.0, atof(usg.optionValue("t", 0).c_str())); + f_init = inRange(0.005, 100000.0, atof(usg.optionValue("f-init", 0).c_str())); + BundleAdjustment_LM<RGBf_Space> bdl; + for (size_t i = 0, I = groups.size(); i < I; ++i) { + messagePrintf(1, "bundle adjust for group %lu", i); + std::vector<SceneInfo<RGBf_Space> > seq; + for (size_t j = 0, J = groups[i].size(); j < J; ++j) { + eyes[groups[i][j]].cameraGet().photoGet().focal(f_init); + seq.push_back(SceneInfo<RGBf_Space>(&(eyes[groups[i][j]]), + CAN_ROTATE | CAN_ZOOM)); + } + bdl.threshold(threshold); + bdl.adjustEye(&seq); + messagePrintf(-1, "ok"); + } + return true; +} + +bool input() { + messagePrintf(1, "loading images"); + for (size_t i = 0, I = eyes.size(); i < I; ++i) { + messagePrintf(1, "%s", bitmap_name[i].c_str()); + cv::Mat img = cv::imread(bitmap_name[i], CV_LOAD_IMAGE_COLOR); + if (!img.data) { + messagePrintf(-1, "opencv read error!, ignore"); + continue; + } + size_t width = img.size().width ; + size_t height = img.size().height; + Bitmap<RGBf_Space> bmp; + bmp.size(height, width, RGBf_Space(0)); + for (size_t x = 0; x < width; x++) { + for (size_t y = 0; y < height; y++) { + RGBi_Space tmp(Vector3D<int>( + img.at<cv::Vec3b>(y, x)[2], + img.at<cv::Vec3b>(y, x)[1], + img.at<cv::Vec3b>(y, x)[0])); + RGBf_Space p; + colorTransformate(tmp, &p); + bmp.pixel(y, x, p); + } + } + eyes[i].cameraGet().photoGet().reset(bmp, eyes[i].camera().photo().focal()); + messagePrintf(-1, "ok"); + } + messagePrintf(-1, "ok"); + return true; +} + +bool output() { + for (size_t i = 0, I = groups.size(); i < I; ++i) { + WatchBall<RGBf_Space> ball; + std::vector<Camera<RGBf_Space> > cs(groups[i].size()); + for (size_t j = 0, J = groups[i].size(); j < J; ++j) { + cs[j].referenceFrom(eyes[groups[i][j]].camera()); + } + ball.cameras(cs); + balls.push_back(ball); + } + double r = inRange(10.0, 100000.0, atof(usg.optionValue("output-radius", 0).c_str())); + messagePrintf(1, "Write images"); + Bitmap<RGBf_Space> bmp; + for (size_t i = 0; i < balls.size(); i++) { + bmp = balls[i].expand(r); + size_t width = bmp.width (); + size_t height = bmp.height(); + cv::Mat img(height, width, CV_8UC3); + for (size_t x = 0; x < width; x++) { + for (size_t y = 0; y < height; y++) { + RGBi_Space tmp; + colorTransformate(bmp.pixel(y, x), &tmp); + img.at<cv::Vec3b>(y, x)[0] = tmp.b(); + img.at<cv::Vec3b>(y, x)[1] = tmp.g(); + img.at<cv::Vec3b>(y, x)[2] = tmp.r(); + } + } + std::string output_name(usg.optionValue("o", 0) + + (balls.size() > 1 ? stringPrintf("%lu", i) : "") + + ".jpg"); + messagePrintf(1, "Write to file '%s'", output_name.c_str()); + if (imwrite(output_name, img) == false) { + messagePrintf(-1, "opencv fail, ignore"); + } + else { + messagePrintf(-1, "%lux%lu, ok", width, height); + } + } + messagePrintf(-1, "ok"); + return true; +} + +int main(int argc, char** argv) { + setup(argc, argv); + read(); + group(); + bundle(); + input(); + output(); + return 0; +} + |