#include <algorithm>
#include <iostream>
#include <string>
#include <time.h>
#include "libmv/base/vector.h"
#include "libmv/base/vector_utils.h"
#include "libmv/base/scoped_ptr.h"
#include "libmv/correspondence/feature.h"
#include "libmv/descriptor/descriptor.h"
#include "libmv/descriptor/simpliest_descriptor.h"
#include "libmv/descriptor/vector_descriptor.h"
#include "libmv/detector/detector.h"
#include "libmv/detector/fast_detector.h"
#include "libmv/detector/star_detector.h"
#include "libmv/detector/surf_detector.h"
#include "libmv/image/image.h"
#include "libmv/image/image_converter.h"
#include "libmv/image/image_drawing.h"
#include "libmv/image/image_io.h"
#include "libmv/tools/tool.h"
using namespace libmv;
using namespace std;
void usage() {
LOG(ERROR)<< " points_detector ImageNameIn.pgm ImageNameOut.pgm " <<std::endl
<< " ImageNameIn : the input image on which features will be \
extrated (jpg,png,pnm), " << std::endl
<< " ImageNameOut.png : the localized keypoints will be displayed on it."
<< std::endl
<< " INFO : output png image only." << std::endl;
}
template <typename Image>
void DrawFeatures( Image & im, const libmv::vector<libmv::Feature *> & feat);
void SaveDescriptorAsPatches(const libmv::vector<descriptor::Descriptor*>&desc);
int main(int argc, char **argv) {
libmv::Init("Extract points feature from an image", &argc, &argv);
if (argc != 3 ) {
usage();
LOG(ERROR) << "Missing parameters or errors in the command line.";
return 1;
}
const string sImageIn = argv[1];
const string sImageOut = argv[2];
ByteImage byteImage;
if ( 0 == ReadImage( sImageIn.c_str(), &byteImage) ) {
LOG(ERROR) << "Failed loading image: " << sImageIn;
return 1;
}
Image imageReference(new ByteImage(byteImage));
if( byteImage.Depth() == 3)
{
ByteImage byteImageGray;
Rgb2Gray(byteImage, &byteImageGray);
imageReference=Image(new ByteImage(byteImageGray));
}
scoped_ptr<detector::Detector> detector(detector::CreateFastDetector(9, 30));
libmv::vector<libmv::Feature *> features;
clock_t startTime = clock();
detector->Detect( imageReference, &features, NULL);
std::cout << " Keypoint localization time : "
<< (float)(clock() - startTime) / CLOCKS_PER_SEC << "s"<< endl;
bool bExportDescToDisk = false;
if( bExportDescToDisk )
{
libmv::vector<descriptor::Descriptor *> descriptors;
scoped_ptr<descriptor::Describer>
descriptorInterface(descriptor::CreateSimpliestDescriber());
descriptorInterface->Describe(features, imageReference, NULL, &descriptors);
SaveDescriptorAsPatches(descriptors);
}
DrawFeatures(*imageReference.AsArray3Du(), features);
if (!WritePng(*imageReference.AsArray3Du(), sImageOut.c_str())) {
LOG(FATAL) << "Failed saving output image: " << sImageOut;
}
DeleteElements(&features);
return 0;
}
template <typename Image>
void DrawFeatures( Image & im, const libmv::vector<libmv::Feature *> & feat)
{
std::cout << feat.size() << " Detected points " <<std::endl;
for (int i = 0; i < feat.size(); ++i)
{
const libmv::PointFeature * feature =
dynamic_cast<libmv::PointFeature *>( feat[i] );
const int x = feature->x();
const int y = feature->y();
const float scale = feature->scale;
DrawCircle(x, y, scale, (unsigned char)255, &im);
const float angle = feature->orientation;
DrawLine(x, y, x + scale * cos(angle), y + scale *sin(angle),
(unsigned char) 255, &im);
}
}
void SaveDescriptorAsPatches( const libmv::vector<descriptor::Descriptor *> & desc)
{
for (int i = 0; i < desc.size(); ++i) {
const descriptor::VecfDescriptor * array =
dynamic_cast<descriptor::VecfDescriptor *>( desc[i] );
if(array) {
const int size = sqrt((double)(array->coords.size()));
Array3Df ima(size,size);
for(int j=0; j< size; ++j)
for(int i=0; i< size; ++i)
{
ima(j, i) = array->coords(j*size + i);
}
ostringstream os;
os << "./Patch_000" << i << ".png";
WritePng(ima, os.str().c_str());
}
}
}