aboutsummaryrefslogtreecommitdiffstats
path: root/meowpp.test
diff options
context:
space:
mode:
Diffstat (limited to 'meowpp.test')
-rw-r--r--meowpp.test/GNUmakefile2
-rwxr-xr-x[-rw-r--r--]meowpp.test/GNUmakefile.dependency.sh0
-rw-r--r--meowpp.test/GNUmakefile.targets14
-rw-r--r--meowpp.test/inc/features__.h1
-rw-r--r--meowpp.test/inc/match.h47
-rw-r--r--meowpp.test/inc/test_utility.h103
-rw-r--r--meowpp.test/src/features.cpp297
-rw-r--r--meowpp.test/src/features_Harris.cpp10
-rw-r--r--meowpp.test/src/match.cpp301
-rw-r--r--meowpp.test/src/rot_bundle.cpp268
10 files changed, 676 insertions, 367 deletions
diff --git a/meowpp.test/GNUmakefile b/meowpp.test/GNUmakefile
index 839be8e..d11c8ff 100644
--- a/meowpp.test/GNUmakefile
+++ b/meowpp.test/GNUmakefile
@@ -74,6 +74,6 @@ dep: $(DEPENDENCY);
$(DEPENDENCYS):: $(DEP)/%.d: $(SRC)/%.cpp
$(DEPENDENCY_CREATER) "`$(CXX_DEP) $(CXXFLAGS) $<`" $@
-$(OBJECTS): $(OBJ)/%.o: $(SRC)/%.cpp $(DEP)/%.d $(DEP)/%.d
+$(OBJECTS): $(OBJ)/%.o: $(SRC)/%.cpp $(DEP)/%.d
@echo 'Objects: $@...'
@$(CXX_OBJ) $(CXXFLAGS) -o $@ $<
diff --git a/meowpp.test/GNUmakefile.dependency.sh b/meowpp.test/GNUmakefile.dependency.sh
index 0d2b65a..0d2b65a 100644..100755
--- a/meowpp.test/GNUmakefile.dependency.sh
+++ b/meowpp.test/GNUmakefile.dependency.sh
diff --git a/meowpp.test/GNUmakefile.targets b/meowpp.test/GNUmakefile.targets
index 5671807..056bfa5 100644
--- a/meowpp.test/GNUmakefile.targets
+++ b/meowpp.test/GNUmakefile.targets
@@ -20,15 +20,15 @@ $(BIN)/oo: $(OBJ)/oo.o $(oo_OBJS)
@echo Target: $@...
@$(CXX) $^ $(CXXFLAGS) `pkg-config --cflags --libs $(oo_LIBS) 2>/dev/null` -o $@
-TARGETS := $(TARGETS) $(BIN)/rot_bundle
-rot_bundle_OBJS :=
-rot_bundle_LIBS := opencv
-$(BIN)/rot_bundle: $(OBJ)/rot_bundle.o $(rot_bundle_OBJS)
- @echo Target: $@...
- @$(CXX) $^ $(CXXFLAGS) `pkg-config --cflags --libs $(rot_bundle_LIBS) 2>/dev/null` -o $@
+#TARGETS := $(TARGETS) $(BIN)/rot_bundle
+#rot_bundle_OBJS :=
+#rot_bundle_LIBS := opencv
+#$(BIN)/rot_bundle: $(OBJ)/rot_bundle.o $(rot_bundle_OBJS)
+# @echo Target: $@...
+# @$(CXX) $^ $(CXXFLAGS) `pkg-config --cflags --libs $(rot_bundle_LIBS) 2>/dev/null` -o $@
TARGETS := $(TARGETS) $(BIN)/features
-features_OBJS :=
+features_OBJS := $(OBJ)/features_Harris.o
features_LIBS := opencv
$(BIN)/features: $(OBJ)/features.o $(features_OBJS)
@echo Target: $@...
diff --git a/meowpp.test/inc/features__.h b/meowpp.test/inc/features__.h
index 85c136b..ab484ae 100644
--- a/meowpp.test/inc/features__.h
+++ b/meowpp.test/inc/features__.h
@@ -18,6 +18,7 @@ public:
virtual meow::Usage usage( ) const = 0;
virtual bool usage(meow::Usage const& usg) = 0;
virtual FeaturePoints detect(meow::Bitmap<meow::RGBf_Space> const& bmp) = 0;
+ virtual size_t dSize() const = 0;
};
static int const kFPSD_ID = 123;
diff --git a/meowpp.test/inc/match.h b/meowpp.test/inc/match.h
new file mode 100644
index 0000000..d05e8e8
--- /dev/null
+++ b/meowpp.test/inc/match.h
@@ -0,0 +1,47 @@
+#ifndef aligement_H__
+#define aligement_H__
+
+#include "meowpp/geo/Vectors.h"
+
+
+struct MatchInfo {
+ meow::Vector2D<double> x_axis;
+ meow::Vector2D<double> y_axis;
+ double x_offset, y_offset;
+ meow::Vector2D<double> depth;
+
+ std::vector<std::pair<Vector2D<double>, Vector2D<double> > > pairs;
+};
+
+class MatchAlls: public meow::ObjBase {
+public:
+ virtual ~MatchAlls() { }
+ virtual std::vector<PairToPair<size_t> > match(
+ std::vector<std::vector<FeaturePoint<double, double> > > > const& fpss) = 0;
+ virtual std::string description() const = 0;
+ virtual meow::Usage usage( ) const = 0;
+ virtual bool usage(meow::Usage const& usg) = 0;
+};
+
+int const kMatchAllsID = 456;
+
+class TryAndChecks: public meow::ObjBase {
+public:
+ virtual TryAndChecks() { }
+ virtual MatchInfo run(std::vector<meow::Vector2D<double> > const& fps1,
+ size_t w1,
+ size_t h1,
+ std::vector<meow::Vector2D<double> > const& fps2,
+ size_t w2,
+ size_t h2,
+ std::vector<std::pair<size_t,size_t> >const& pairs) = 0;
+ virtual std::string description() const = 0;
+ virtual meow::Usage usage( ) const = 0;
+ virtual bool usage(meow::Usage const& usg) = 0;
+ virtual int minNumber() const = 0;
+};
+
+int const kTryAndChecksID = 123;
+
+
+#endif // aligement_H__
diff --git a/meowpp.test/inc/test_utility.h b/meowpp.test/inc/test_utility.h
new file mode 100644
index 0000000..8875445
--- /dev/null
+++ b/meowpp.test/inc/test_utility.h
@@ -0,0 +1,103 @@
+#ifndef TEST_UTILITY_H__
+#define TEST_UTILITY_H__
+
+#include <opencv/cv.h>
+#include <opencv/highgui.h>
+
+#include <cstdarg>
+#include <queue>
+
+extern "C" {
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <dirent.h>
+}
+
+#include "meowpp/colors/RGB_Space.h"
+#include "meowpp/gra/Bitmap.h"
+#include "meowpp/utility.h"
+
+#include <cstdio>
+#include <string>
+
+template<class T>
+inline bool readBitmap(std::string const& name, meow::Bitmap<T>* bmp) {
+ cv::Mat img = cv::imread(name, CV_LOAD_IMAGE_COLOR);
+ if (!img.data)
+ return false;
+ size_t height = img.size().height;
+ size_t width = img.size().width ;
+ bmp->size(height, width, T(0));
+ for (size_t y = 0; y < height; ++y)
+ for (size_t x = 0; x < width; ++x) {
+ meow::RGBi_Space tmp;
+ for (size_t i = 0; i < 3; ++i)
+ tmp.rgb(i, img.at<cv::Vec3b>(y, x)[2 - i]);
+ T p;
+ meow::colorTransformate(tmp, &p);
+ bmp->pixel(y, x, p);
+ }
+ return true;
+}
+
+template<class T>
+inline bool writeBitmap(std::string const& name, meow::Bitmap<T> const& bmp) {
+ size_t height = bmp.height();
+ size_t width = bmp.width ();
+ cv::Mat img(height, width, CV_8UC3);
+ for (size_t y = 0; y < height; y++)
+ for (size_t x = 0; x < width; x++) {
+ meow::RGBi_Space tmp;
+ meow::colorTransformate(bmp.pixel(y, x), &tmp);
+ for (size_t i = 0; i < 3; ++i)
+ img.at<cv::Vec3b>(y, x)[i] = tmp.rgb(2 - i);
+ }
+ return imwrite(name, img);
+}
+
+inline std::vector<std::string> cgetFiles(char const* dn, bool recur, int num, ...) {
+ va_list args;
+ va_start(args, num);
+ std::vector<char const*> filter(num);
+ for (int i = 0; i < num; ++i)
+ filter[i] = va_arg(args, char const*);
+
+ std::string name(dn);
+ if (dn[0] != '\0' && dn[strlen(dn) - 1] != '/')
+ name = name + "/";
+
+ std::queue<std::string> dirs;
+ std::vector<std::string> ret;
+ struct stat st;
+
+ for (dirs.push(name); !dirs.empty(); dirs.pop()) {
+ DIR* dir = opendir(dirs.front().c_str());
+ if (dir == NULL)
+ continue;
+ for (dirent* ent; (ent = readdir(dir)) != NULL; ) {
+ if (strcmp(ent->d_name, ".") == 0 || strcmp(ent->d_name, "..") == 0)
+ continue;
+ std::string fname(dirs.front() + ent->d_name);
+ if (stat(fname.c_str(), &st) < 0)
+ continue;
+ if (S_ISDIR(st.st_mode) && recur) {
+ dirs.push(fname + "/");
+ continue;
+ }
+ if (S_ISREG(st.st_mode)) {
+ bool ok = false;
+ for (int i = 0; i < num && !ok; ++i)
+ ok = meow::cstringEndWith(fname.c_str(), 1, filter[i]);
+ if (ok)
+ ret.push_back(fname);
+ }
+ }
+ closedir(dir);
+ }
+
+ va_end(args);
+ return ret;
+}
+
+#endif // TEST_UTILITY_H__
diff --git a/meowpp.test/src/features.cpp b/meowpp.test/src/features.cpp
index 2da188a..6972fa3 100644
--- a/meowpp.test/src/features.cpp
+++ b/meowpp.test/src/features.cpp
@@ -1,34 +1,89 @@
#include <cstdio>
+#include <string>
+#include <cstdlib>
-#include "features__.h"
+struct Job;
-#include "meowpp/Usage.h"
-#include "meowpp/colors/RGB_Space.h"
-#include "meowpp/geo/Vectors.h"
-#include "meowpp/gra/Bitmap.h"
-#include "meowpp/oo/ObjBase.h"
-#include "meowpp/oo/ObjSelector.h"
+void init ( );
+void setup(int argc, char** argv);
+void end ( );
-#include <opencv/cv.h>
-#include <opencv/highgui.h>
+Job* get(size_t counter);
-extern "C"{
-#include <sys/types.h>
-#include <dirent.h>
+void input (Job* job);
+void handle(Job* job);
+void output(Job* job);
+void clear (Job* job);
+
+void info0 (Job* job);
+void info1 (Job* job);
+void info2 (Job* job);
+
+int main(int argc, char** argv) {
+ Job* now;
+ try {
+ init();
+ setup(argc, argv);
+ for (size_t counter = 0; (now = get(counter)) != NULL; clear(now), ++counter) {
+ try {
+ input (now); info0(now);
+ handle(now); info1(now);
+ output(now); info2(now);
+ }
+ catch (std::string reason) {
+ throw reason.c_str();
+ }
+ catch (char const* reason) {
+ printf("fail '%s', ignore.\n\n", reason);
+ continue;
+ }
+ printf("\n");
+ }
+ end();
+ }
+ catch (int num) {
+ return num;
+ }
+ return 0;
}
+///////////////////////////////////////////////////////////
+
+#include "test_utility.h"
+#include "features__.h"
+
+#include "meowpp/utility.h"
+#include "meowpp/Usage.h"
+#include "meowpp/oo/ObjSelector.h"
+
#include <vector>
#include <algorithm>
#include <string>
+#include <cstdio>
using namespace meow;
+///////////////////////////////////////////////////////////
+
Usage usg("features");
+FeaturePointsDetectors* detector;
+
+struct Job {
+ int id;
+ std::string file_name;
+ std::vector<FeaturePoint<double, double> > fps;
+ Bitmap<RGBf_Space> bmp;
+};
+
std::vector<std::string> names;
-std::vector<std::vector<FeaturePoint<double, double> > > fps;
-int setup(int argc, char** argv) {
+std::string out_pre;
+
+
+///////////////////////////////////////////////////////////
+
+void init() {
usg.optionAdd("h" , "Display this help document");
usg.optionAdd("help", "Display this help document");
usg.optionAdd("i",
@@ -37,16 +92,13 @@ int setup(int argc, char** argv) {
"pathname",
"",
false);
+ usg.optionAdd("r",
+ "recur");
usg.optionAdd("o",
"Output images with denoting feature points",
"filename",
"",
false);
- usg.optionAdd("f",
- "Output text file name",
- "filename",
- "<<input image name>>.txt",
- false);
usg.optionAdd("d",
"Specify which feature detect algorithm to use",
"name",
@@ -54,179 +106,100 @@ int setup(int argc, char** argv) {
true);
std::vector<std::string> algo_list(ObjSelector<kFPSD_ID>::names());
for (size_t i = 0, I = algo_list.size(); i < I; ++i) {
- FeaturePointsDetectors const* f;
- f = (FeaturePointsDetectors const*)ObjSelector<kFPSD_ID>::get(algo_list[i]);
+ FeaturePointsDetectors const* f = (FeaturePointsDetectors const*)ObjSelector<kFPSD_ID>::get(algo_list[i]);
usg.optionValueAcceptAdd("d", algo_list[i], f->description());
- usg.import(f->usage());
+ if (usg.import(f->usage()) == false) throw -1;
}
+}
+
+void setup(int argc, char** argv) {
std::string err;
bool ret = usg.arguments(argc, argv, &err);
if (usg.hasOptionSetup("h") || usg.hasOptionSetup("help")) {
fprintf(stderr, "%s\n", usg.usage().c_str());
- return 0;
+ throw 0;
}
if (ret == false) {
fprintf(stderr, "%s\n", err.c_str());
- return -1;
+ throw -2;
}
- return 1;
-}
-int getName() {
- if (usg.hasOptionSetup("i") == false) {
- names = usg.procArgs();
+ detector = (FeaturePointsDetectors*)ObjSelector<kFPSD_ID>::create(usg.optionValue("d", 0));
+ if (detector->usage(usg) == false) throw -3;
+
+ if (usg.hasOptionSetup("i")) {
+ names = cgetFiles(usg.optionValue("i", 0).c_str(), usg.hasOptionSetup("r"),
+ 4, ".jpg", ".jpeg", ".JPG", ".JPEG");
}
else {
- std::string base = usg.optionValue("i", 0);
- if (base.length() == 0 || base[base.length() - 1] != '/') {
- base += "/";
- }
- DIR* dir = opendir(base.c_str());
- if (!dir) {
- fprintf(stderr, "can't open dir '%s'\n", base.c_str());
- return -1;
- }
- for (dirent* ent; (ent = readdir(dir)) != NULL; ) {
- if (!cstringEndWith(ent->d_name, 4, ".jpeg", ".jpg", ".JPG", ".JPEG")) {
- continue;
- }
- names.push_back(base + std::string(ent->d_name));
- }
+ names = usg.procArgs();
}
- return 1;
+ std::sort(names.begin(), names.end(), filenameCompare);
+ out_pre = usg.optionValue("o", 0);
}
-Bitmap<RGBf_Space> readOne(std::string name) {
- Bitmap<RGBf_Space> ret;
- messagePrintf(1, "Loading image...");
- cv::Mat img = cv::imread(name, CV_LOAD_IMAGE_COLOR);
- if (img.data) {
- size_t height = img.size().height;
- size_t width = img.size().width ;
- ret.size(height, width, RGBf_Space(0));
- for (size_t y = 0; y < height; ++y) {
- for (size_t x = 0; x < width; ++x) {
- Vector3D<int> v;
- for (size_t i = 0; i < 3; ++i)
- v.scalar(i, img.at<cv::Vec3b>(y, x)[2 - i]);
- RGBf_Space p;
- colorTransformate(RGBi_Space(v), &p);
- ret.pixel(y, x, p);
- }
- }
- }
- messagePrintf(-1, (ret.size() > 0 ? "ok" : "fail"));
- return ret;
+void end() {
+ delete detector;
}
-int features() {
- std::string n(usg.optionValue("d", 0));
- FeaturePointsDetectors* fpd((FeaturePointsDetectors*)
- ObjSelector<kFPSD_ID>::create(n));
- if (fpd->usage(usg) == false) {
- fprintf(stderr, "\nArgument setup error for '%s'\n", n.c_str());
- return -1;
- }
- for (size_t i = 0, I = names.size(); i < I; ++i) {
- messagePrintf(1, "Finding feature points of '%s'", names[i].c_str());
- Bitmap<RGBf_Space> bmp(readOne(names[i]));
- if (bmp.size() == 0) {
- messagePrintf(-1, "fail");
- continue;
- }
- messagePrintf(0, "Height x Width = %lux%lu", bmp.height(), bmp.width());
- fps.push_back(fpd->detect(bmp));
- messagePrintf(-1, "ok");
- }
- delete fpd;
- return 1;
-}
+///////////////////////////////////////////////////////////
-int writeOne(FILE* f, size_t i) {
- if (fprintf(f, "%d\n", (int)fps[i].size()) < 1) return -1;
- for (size_t j = 0, J = fps[i].size(); j < J; ++j) {
- if (fps[i][j].write(f, false, 0) == false) return -1;
- }
- return 1;
+Job* get(size_t counter) {
+ if (counter >= names.size())
+ return NULL;
+ Job* job = new Job;
+ job->id = counter;
+ job->file_name = names[counter];
+ return job;
}
-int writeText() {
- for (size_t i = 0, I = fps.size(); i < I; ++i) {
- std::string name2;
- if (usg.hasOptionSetup("f")) { name2 = usg.optionValue("f", i); }
- else { name2 = names[i] + ".txt"; }
- messagePrintf(1, "Write text file to '%s'", name2.c_str());
- FILE* f = fopen(name2.c_str(), "w");
- if (f == NULL) {
- messagePrintf(-1, "fail to open file!, ignore");
- continue;
- }
- if (writeOne(f, i) < 0) {
- messagePrintf(-1, "write fail");
- fclose(f);
- continue;
- }
- fclose(f);
- messagePrintf(-1, "ok");
- }
- return 1;
+///////////////////////////////////////////////////////////
+
+void input(Job* job) {
+ if (readBitmap(job->file_name, &(job->bmp)) == false)
+ throw("cannot open image");
}
-int writeBmpOne(std::string name, Bitmap<RGBf_Space> const& bmp) {
- size_t height = bmp.height();
- size_t width = bmp.width ();
- cv::Mat img(height, width, CV_8UC3);
- for (size_t y = 0; y < height; y++) {
- for (size_t x = 0; x < width; x++) {
- RGBi_Space tmp;
- colorTransformate(bmp.pixel(y, x), &tmp);
- for (size_t i = 0; i < 3; ++i)
- img.at<cv::Vec3b>(y, x)[i] = tmp.rgb(2 - i);
- }
- }
- if (imwrite(name, img) == false) {
- return -1;
- }
- return 1;
+void handle(Job* job) {
+ job->fps = detector->detect(job->bmp);
}
-int writeBmp() {
- if (usg.hasOptionSetup("o") == false)
- return 1;
- for (size_t i = 0, I = names.size(); i < I; ++i) {
- std::string name2;
- name2 = stringPrintf("%s%lu.jpg", usg.optionValue("o", 0).c_str(), i);
- messagePrintf(1, "Write img file to '%s'", name2.c_str());
- Bitmap<RGBf_Space> bmp(readOne(names[i]));
- bool succ;
- if ((succ = (bmp.size() > 0))) {
- int wh = std::min(bmp.height(), bmp.width()) / 16;
- for (size_t j = 0, J = fps[i].size(); j < J; ++j) {
- int x0 = fps[i][j].position()(0);
- int y0 = fps[i][j].position()(1);
- for (int dx = -wh; dx <= wh; ++dx)
- if (0 <= x0 + dx && x0 + dx < (int)bmp.width())
- bmp.pixel(y0, x0 + dx, RGBf_Space(Vector3D<double>(1.0, 0.0, 0.0)));
- for (int dy = -wh; dy <= wh; ++dy)
- if (0 <= y0 + dy && y0 + dy < (int)bmp.height())
- bmp.pixel(y0 + dy, x0, RGBf_Space(Vector3D<double>(1.0, 0.0, 0.0)));
- }
- succ = (writeBmpOne(name2, bmp) > 0);
+void output(Job *job) {
+ FILE* f = fopen((job->file_name + ".fps").c_str(), "w");
+ fprintf(f, "%d %d\n%d\n",
+ (int)job->bmp.width(), (int)job->bmp.height(), (int)job->fps.size());
+ for (size_t i = 0, I = job->fps.size(); i < I; ++i) {
+ job->fps[i].write(f, false, 0);
+ }
+ fclose(f);
+ if (out_pre.size() > 0) {
+ for (size_t i = 0, I = job->fps.size(); i < I; ++i) {
+ int x0 = job->fps[i].position()(0);
+ int y0 = job->fps[i].position()(1);
+ int w = std::min(job->bmp.width(), job->bmp.height()) / 32;
+ for (int x = x0 - w; x <= x0 + w; ++x)
+ if (0 <= x && x < (int)job->bmp.width())
+ job->bmp.pixel(y0, x, RGBf_Space(Vector3D<double>(1.0, 0.0, 0.0)));
+ for (int y = y0 - w; y <= y0 + w; ++y)
+ if (0 <= y && y < (int)job->bmp.height())
+ job->bmp.pixel(y, x0, RGBf_Space(Vector3D<double>(1.0, 0.0, 0.0)));
}
- messagePrintf(0, "ok");
+ writeBitmap(stringPrintf("%s%d.jpg", out_pre.c_str(), job->id), job->bmp);
}
- return 1;
}
-int main(int argc, char** argv) {
- int ret;
- if ((ret = setup(argc, argv)) <= 0) return ret;
- if ((ret = getName()) <= 0) return ret;
- if ((ret = features()) <= 0) return ret;
- if ((ret = writeText()) <= 0) return ret;
- if ((ret = writeBmp()) <= 0) return ret;
- return 0;
+void clear(Job *job) {
+ delete job;
}
+void info0(Job* job) {
+ printf("file name: %s, %dx%d\n",
+ job->file_name.c_str(), (int)job->bmp.width(), (int)job->bmp.height());
+}
+void info1(Job* job) {
+ printf("# of feature points: %d\n", (int)job->fps.size());
+}
+void info2(Job* job) {
+}
diff --git a/meowpp.test/src/features_Harris.cpp b/meowpp.test/src/features_Harris.cpp
index f3c2c10..eeb2f2d 100644
--- a/meowpp.test/src/features_Harris.cpp
+++ b/meowpp.test/src/features_Harris.cpp
@@ -14,7 +14,7 @@ class Harris: public FeaturePointsDetectors {
std::string description() const {
return "Harris-Corner-Detect";
}
-
+
Usage usage() const {
Usage ret;
ret.optionAdd("harris-k",
@@ -55,7 +55,7 @@ class Harris: public FeaturePointsDetectors {
false);
return ret;
}
-
+
bool usage(meow::Usage const& usg) {
double K = atof(usg.optionValue("harris-k", 0).c_str());
double R = atof(usg.optionValue("harris-r", 0).c_str());
@@ -73,11 +73,15 @@ class Harris: public FeaturePointsDetectors {
detector_.paramB(B);
return true;
}
-
+
FeaturePoints detect(Bitmap<RGBf_Space> const& bmp) {
return detector_.detect(bmp);
}
+ size_t dSize() const {
+ return detector_.descriptionDimension();
+ }
+
std::string type() const { return std::string("Harris"); }
ObjBase* create() const { return new Harris(); }
};
diff --git a/meowpp.test/src/match.cpp b/meowpp.test/src/match.cpp
new file mode 100644
index 0000000..c69b958
--- /dev/null
+++ b/meowpp.test/src/match.cpp
@@ -0,0 +1,301 @@
+#include <cstdio>
+
+#include "match.h"
+
+#include "meowpp/Usage.h"
+#include "meowpp/colors/RGB_Space.h"
+#include "meowpp/geo/Vectors.h"
+#include "meowpp/gra/Bitmap.h"
+#include "meowpp/oo/ObjBase.h"
+#include "meowpp/oo/ObjSelector.h"
+
+#include <opencv/cv.h>
+#include <opencv/highgui.h>
+
+extern "C"{
+#include <sys/types.h>
+#include <dirent.h>
+}
+
+#include <vector>
+#include <algorithm>
+#include <string>
+
+using namespace meow;
+
+Usage usg("match");
+
+std::vector<bool> fg;
+std::vector<std::string> names;
+std::vector<std::vector<FeaturePoint<double, double> > > fps;
+
+int setup(int argc, char** argv) {
+ usg.optionAdd("h" , "Display this help document");
+ usg.optionAdd("help", "Display this help document");
+ usg.optionAdd("i",
+ "Specify the input images are in a directory instead of"
+ " process arguments",
+ "pathname",
+ "",
+ false);
+ usg.optionAdd("o",
+ "Output images with denoting aligement points",
+ "filename",
+ "",
+ false);
+ usg.optionAdd("f",
+ "Output text file name (prefix)",
+ "filename",
+ "output",
+ false);
+ usg.optionAdd("m",
+ "Specify which match algorithm to use",
+ "name",
+ "",
+ true);
+ usg.optionAdd("c",
+ "Specify which check algorithm to use",
+ "name",
+ "",
+ true);
+ std::vector<std::string> nlist;
+ nlist = (ObjSelector<kMatchAllsID>::names());
+ for (size_t i = 0, I = nlist.size(); i < I; ++i) {
+ MatchAlls const* m;
+ m = (MatchAlls const*)ObjSelector<kMatchAllsID>::get(nlist[i]);
+ usg.optionValueAcceptAdd("m", nlist[i], m->description());
+ usg.import(m->usage());
+ }
+ nlist = ObjSelector<kMatchAllsID>::names();
+ for (size_t i = 0, I = nlist.size(); i < I; ++i) {
+ TryAndChecks const* m;
+ m = (TryAndChecks const*)ObjSelector<kTryAndChecks>::get(nlist[i]);
+ usg.optionValueAcceptAdd("c", nlist[i], m->description());
+ usg.import(m->usage());
+ }
+ std::string err;
+ bool ret = usg.arguments(argc, argv, &err);
+ if (usg.hasOptionSetup("h") || usg.hasOptionSetup("help")) {
+ fprintf(stderr, "%s\n", usg.usage().c_str());
+ return 0;
+ }
+ if (ret == false) {
+ fprintf(stderr, "%s\n", err.c_str());
+ return -1;
+ }
+ return 1;
+}
+
+int getName() {
+ if (usg.hasOptionSetup("i") == false) {
+ names = usg.procArgs();
+ }
+ else {
+ std::string base = usg.optionValue("i", 0);
+ if (base.length() == 0 || base[base.length() - 1] != '/') {
+ base += "/";
+ }
+ DIR* dir = opendir(base.c_str());
+ if (!dir) {
+ fprintf(stderr, "can't open dir '%s'\n", base.c_str());
+ return -1;
+ }
+ for (dirent* ent; (ent = readdir(dir)) != NULL; ) {
+ if (!cstringEndWith(ent->d_name, 4, ".jpeg", ".jpg", ".JPG", ".JPEG")) {
+ continue;
+ }
+ names.push_back(base + std::string(ent->d_name) + ".txt");
+ }
+ }
+ fg.resize(names.size(), true);
+ return 1;
+}
+
+int readIn() {
+ std::vector<std::string> nn(names);
+ names.clear();
+ for (int i = 0, I = nn.size(); i < I; ++i) {
+ messagePrintf(1, "read '%s'", nn[i].c_str());
+ FILE* f = fopen(nn[i].c_str(), "r");
+ if (f == NULL) {
+ messagePrintf(-1, "cannot open, ignore");
+ continue;
+ }
+ std::vector<FeaturePoint<double, double> > tmp;
+ bool succ = true;
+ int N = 0, M;
+ if (fscanf(f, "%d %d", &N, &M) < 1) succ = false;
+ if (succ) {
+ tmp.resize(N);
+ for (size_t i = 0; i < N; ++i) {
+ if (tmp[i].read(f, false, 0) == false) {
+ succ = false;
+ break;
+ }
+ if ((int)tmp[i].description().diemnsion() != M) {
+ succ = false;
+ break;
+ }
+ }
+ }
+ fclose(f);
+ if (succ) {
+ names.push_back(nn[i]);
+ fps .push_back(tmp);
+ messagePrintf(-1, "ok");
+ }
+ else {
+ messagePrintf(-1, "file format error");
+ }
+ }
+ return fps.size();
+}
+
+int match() {
+ MatchAlls* algo = ObjSelector<kMatchAllsID>::create(usg.optionValeu("m", 0));
+ if (algo->usage(usg) == false) {
+ delete algo;
+ messagePrintf(0, "usage error");
+ return -1;
+ }
+ std::vector<PairToPair<size_t> > p = algo->match(fps);
+ for (size_t i = 0, I = p.size(); i < I; ++i) {
+ std::pair<size_t, size_t> pr(p[i].from.second, p[i].to.second);
+ pairs[p[i].from.first][p[i].to.first].push_back(pr);
+ }
+ delete algo;
+ return 1;
+}
+
+int check() {
+ TryAndChecks*chk=ObjSelector<kTryAndChecksID>::create(usg.optionValue("c",0));
+ for (size_t i = 0, I = names.size(); i < I; ++i) {
+ for (size_t j = 0; j < I; ++j) {
+ match[i][j].pairs.clear();
+ if (i != j && pairs[i][j].size() >= chk->minNumber()) {
+ match[i][j] = chk->run(fps[i], width[i], height[i],
+ fps[j], width[j], height[j],
+ pairs[i][j]);
+ }
+ }
+ }
+ delete chk;
+ return 1;
+}
+
+Bitmap<RGBf_Space> readOne(std::string name) {
+ Bitmap<RGBf_Space> ret;
+ messagePrintf(1, "Loading image...");
+ cv::Mat img = cv::imread(name, CV_LOAD_IMAGE_COLOR);
+ if (img.data) {
+ size_t height = img.size().height;
+ size_t width = img.size().width ;
+ ret.size(height, width, RGBf_Space(0));
+ for (size_t y = 0; y < height; ++y) {
+ for (size_t x = 0; x < width; ++x) {
+ Vector3D<int> v;
+ for (size_t i = 0; i < 3; ++i)
+ v.scalar(i, img.at<cv::Vec3b>(y, x)[2 - i]);
+ RGBf_Space p;
+ colorTransformate(RGBi_Space(v), &p);
+ ret.pixel(y, x, p);
+ }
+ }
+ }
+ messagePrintf(-1, (ret.size() > 0 ? "ok" : "fail"));
+ return ret;
+}
+
+int writeBmpOne(std::string name, Bitmap<RGBf_Space> const& bmp) {
+ size_t height = bmp.height();
+ size_t width = bmp.width ();
+ messagePrintf(1, "write to image '%s' (%lu x %lu)",
+ name.c_str(), height, width);
+ cv::Mat img(height, width, CV_8UC3);
+ for (size_t y = 0; y < height; y++) {
+ for (size_t x = 0; x < width; x++) {
+ RGBi_Space tmp;
+ colorTransformate(bmp.pixel(y, x), &tmp);
+ for (size_t i = 0; i < 3; ++i)
+ img.at<cv::Vec3b>(y, x)[i] = tmp.rgb(2 - i);
+ }
+ }
+ if (imwrite(name, img) == false) {
+ messagePrintf(-1, "fail");
+ return -1;
+ }
+ messagePrintf(-1, "ok");
+ return 1;
+}
+
+int writeBmp(size_t id) {
+ if (usg.hasOptionSetup("o") == false)
+ return 1;
+ std::string name2;
+ name2 = stringPrintf("%s%lu.jpg", usg.optionValue("o", 0).c_str(), id);
+ messagePrintf(1, "Write img file to '%s'", name2.c_str());
+ Bitmap<RGBf_Space> bmp(readOne(names[id]));
+ bool succ;
+ if ((succ = (bmp.size() > 0))) {
+ int wh = std::min(bmp.height(), bmp.width()) / 32;
+ for (size_t j = 0, J = fps[id].size(); j < J; ++j) {
+ int x0 = fps[id][j].position()(0);
+ int y0 = fps[id][j].position()(1);
+ for (int dx = -wh; dx <= wh; ++dx)
+ if (0 <= x0 + dx && x0 + dx < (int)bmp.width())
+ bmp.pixel(y0, x0 + dx, RGBf_Space(Vector3D<double>(1.0, 0.0, 0.0)));
+ for (int dy = -wh; dy <= wh; ++dy)
+ if (0 <= y0 + dy && y0 + dy < (int)bmp.height())
+ bmp.pixel(y0 + dy, x0, RGBf_Space(Vector3D<double>(1.0, 0.0, 0.0)));
+ }
+ succ = (writeBmpOne(name2, bmp) > 0);
+ }
+ messagePrintf(-1, succ ? "ok" : "fail");
+ return 1;
+}
+
+int writeOne(FILE* f, size_t i) {
+ if (fprintf(f, "%d\n", (int)fps[i].size()) < 1) return -1;
+ for (size_t j = 0, J = fps[i].size(); j < J; ++j) {
+ if (fps[i][j].write(f, false, 0) == false) return -1;
+ }
+ return 1;
+}
+
+int writeText() {
+ for(size_t i = 0, I = fps.size(); i < I; ++i) {
+ if (!fg[i]) continue;
+ std::string name2;
+ if (usg.hasOptionSetup("f")) { name2 = usg.optionValue("f", i); }
+ else { name2 = names[i] + ".txt"; }
+ messagePrintf(1, "Write text file to '%s'", name2.c_str());
+ FILE* f = fopen(name2.c_str(), "w");
+ if (f == NULL) {
+ messagePrintf(-1, "fail to open file!, ignore");
+ continue;
+ }
+ if (writeOne(f, i) < 0) {
+ messagePrintf(-1, "write fail");
+ fclose(f);
+ continue;
+ }
+ fclose(f);
+ messagePrintf(-1, "ok");
+ }
+ return 1;
+}
+
+int main(int argc, char** argv) {
+ int ret;
+ if ((ret = setup(argc, argv)) <= 0) return ret;
+ if ((ret = getName()) <= 0) return ret;
+ if ((ret = readIn()) <= 0) return ret;
+ if ((ret = match()) <= 0) return ret;
+ if ((ret = check()) <= 0) return ret;
+ if ((ret = writeText()) <= 0) return ret;
+ if ((ret = writeBmp()) <= 0) return ret;
+ return 0;
+}
+
+
+
diff --git a/meowpp.test/src/rot_bundle.cpp b/meowpp.test/src/rot_bundle.cpp
index 38ffce8..775c573 100644
--- a/meowpp.test/src/rot_bundle.cpp
+++ b/meowpp.test/src/rot_bundle.cpp
@@ -25,16 +25,12 @@ 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;
+std::vector<std::string > names;
+std::vector<Eye<RGBf_Space> > eyes;
-double f_init;
-double threshold;
+double f_init = 300;
+double threshold = 5;
+double r = 1000;
//////////////////////////////////////////////////////////////////
@@ -49,7 +45,7 @@ bool setup(int argc, char** argv) {
usg.optionAdd("output-radius",
"...",
"floating point",
- "1000",
+ stringPrintf("%f", r),
false);
usg.optionAdd("o",
"prefix of output images",
@@ -59,12 +55,12 @@ bool setup(int argc, char** argv) {
usg.optionAdd("f-init",
"init focal length",
"floating point",
- "300.0",
+ stringPrintf("%f", f_init),
false);
usg.optionAdd("t",
"threshold for bundle adjustment",
"floating point",
- "5.0",
+ stringPrintf("%f", threshold),
false);
std::string s;
bool ok = usg.arguments(argc, argv, &s);
@@ -79,166 +75,60 @@ bool setup(int argc, char** argv) {
return true;
}
+void fmtError(FILE* f) {
+ fclose(f);
+ fprintf(stderr, "\nFromat error!\n");
+ exit(-1);
+}
+
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);
+ if (fscanf(f, "%lu", &N) < 1) fmtError(f);
+ names[i].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.scalar(0, x - center[i].x());
- v.scalar(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().pointAdd(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);
- }
+ if (fscanf(f, "%s", s) < 1) fmtError(f);
+ names[i] = s;
}
- // 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, "");
+ eyes.resize(N);
+ size_t M;
+ if (fscanf(f, "%lu", &M) < 1) fmtError(f);
+ for (size_t i = 0; i < M; ++M) {
+ int a, b;
+ double x1, y1, x2, y2;
+ if (fscanf(f, "%d %lf %lf %d %lf %lf", &a, &x1, &y1, &b, &x2, &y2) < 6) fmtError(f);
+ eyes[a].cameraGet().fixedPoints2DGet().pointAdd(i, Vector2D(x1, y1).matrix());
+ eyes[b].cameraGet().fixedPoints2DGet().pointAdd(i, Vector2D(x2, y2).matrix());
}
+ fclose(f);
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()));
+ messagePrintf(1, "boundle adjustment");
+ threshold = inRange(0.0005, 1000.0, atof(usg.optionValue("t" , 0).c_str()));
+ f_init = inRange(0.0005, 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");
+ bdl.threshold(threshold);
+ std::vector<SceneInfo<RGBf_Space> > seq;
+ for (size_t i = 0, I = eyes.size(); i < I; ++i) {
+ eyes[i].cameraGet().photoGet().focal(f_init);
+ seq.push_back(SceneInfo<RGBf_Space>(eyes[i], CAN_ROTATE | CAN_ZOOM));
}
+ bdl.adjustEyes(&seq);
+ messagePrintf(-1, "ok");
return true;
}
-bool input() {
- messagePrintf(1, "loading images");
+bool output() {
+ r = inRange(10.0, 100000.0, atof(usg.optionValue("output-radius", 0).c_str()));
+ Bitmap<RGBf_Space> output;
+ Bitmap<double> alpha;
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);
+ messagePrintf(1, "load image");
+ cv::Mat img = cv::imread(names[i], CV_LOAD_IMAGE_COLOR);
if (!img.data) {
messagePrintf(-1, "opencv read error!, ignore");
continue;
@@ -258,51 +148,42 @@ bool input() {
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) {
+ eyes[i].cameraGet().photoGet().bitmap(bmp);
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(std::vector<Camera<RGBf_Space> >(1, eyes[i].camera()));
+ std::pair<Bitmap<RGBf_Space>, Bitmap<double> > p = ball.expandAlpha(r);
+ if (output.size() == 0) {
+ output = p.first;
+ alpha = p.second;
+ }
+ else {
+ output.matrix(output.matrix() + p.first .matrix());
+ alpha .matrix(alpha .matrix() + p.second.matrix());
}
- ball.cameras(cs);
- balls.push_back(ball);
}
- double r = inRange(10.0, 100000.0, atof(usg.optionValue("output-radius", 0).c_str()));
+ for (size_t y = 0, Y = output.height(); y < Y; ++y)
+ for (size_t x = 0, X = output.width(); x < X; ++x)
+ if (noEPS(alpha.pixel(y, x)) > 0)
+ output.pixel(y, x, output.pixel(y, x) / alpha.pixel(y, x));
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);
+ 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(output.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) + ".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;
}
@@ -310,7 +191,6 @@ bool output() {
int main(int argc, char** argv) {
setup(argc, argv);
read();
- group();
bundle();
input();
output();