#include #include "features__.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 #include extern "C"{ #include #include } #include #include #include using namespace meow; Usage usg("features"); std::vector names; std::vector > > 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 feature points", "filename", "", false); usg.optionAdd("f", "Output text file name", "filename", "<>.txt", false); usg.optionAdd("d", "Specify which feature detect algorithm to use", "name", "", true); std::vector algo_list(ObjSelector::names()); for (size_t i = 0, I = algo_list.size(); i < I; ++i) { FeaturePointsDetectors const* f; f = (FeaturePointsDetectors const*)ObjSelector::get(algo_list[i]); usg.optionValueAcceptAdd("d", algo_list[i], f->description()); usg.import(f->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)); } } return 1; } Bitmap readOne(std::string name) { Bitmap 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 v; for (size_t i = 0; i < 3; ++i) v.scalar(i, img.at(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 features() { std::string n(usg.optionValue("d", 0)); FeaturePointsDetectors* fpd((FeaturePointsDetectors*) ObjSelector::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 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; } 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; } int writeBmpOne(std::string name, Bitmap 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(y, x)[i] = tmp.rgb(2 - i); } } if (imwrite(name, img) == false) { return -1; } return 1; } 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 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(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(1.0, 0.0, 0.0))); } succ = (writeBmpOne(name2, bmp) > 0); } messagePrintf(0, "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 = features()) <= 0) return ret; if ((ret = writeText()) <= 0) return ret; if ((ret = writeBmp()) <= 0) return ret; return 0; }