PageRenderTime 34ms CodeModel.GetById 19ms app.highlight 12ms RepoModel.GetById 1ms app.codeStats 0ms

/demos/pmatch-gui/src/main.cc

https://bitbucket.org/tetonedge/libsrvf
C++ | 220 lines | 170 code | 32 blank | 18 comment | 20 complexity | 3c0179a173f5ff74be8026317c78c2c9 MD5 | raw file
Possible License(s): GPL-3.0
  1/*
  2 * LibSRVF - a shape analysis library using the square root velocity framework.
  3 *
  4 * Copyright (C) 2012  FSU Statistical Shape Analysis and Modeling Group
  5 * 
  6 * This program is free software: you can redistribute it and/or modify
  7 * it under the terms of the GNU General Public License as published by
  8 * the Free Software Foundation, either version 3 of the License, or
  9 * (at your option) any later version.
 10 * 
 11 * This program is distributed in the hope that it will be useful,
 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 14 * GNU General Public License for more details.
 15 * 
 16 * You should have received a copy of the GNU General Public License
 17 * along with this program.  If not, see <http://www.gnu.org/licenses/>
 18 */
 19#include "matchview.h"
 20#include "ui.h"
 21
 22#include <srvf/partialmatch.h>
 23#include <srvf/paretoset.h>
 24
 25#include <srvf/matrix.h>
 26#include <srvf/plf.h>
 27#include <srvf/srvf.h>
 28#include <srvf/qmap.h>
 29#include <srvf/fileio.h>
 30
 31#include <FL/Fl.H>
 32
 33#include <iostream>
 34#include <fstream>
 35#include <cstdlib>
 36#include <unistd.h>
 37
 38#define DEFAULT_GRID_WIDTH 0
 39#define DEFAULT_GRID_HEIGHT 0
 40
 41
 42static void do_usage(const char *progname)
 43{
 44  std::cout << "USAGE: " << progname << " [OPTIONS] file1 file2" << std::endl;
 45  std::cout << "where" << std::endl;
 46  std::cout << "  file1 contains samples for the first curve" << std::endl;
 47  std::cout << "  file2 contains samples for the second curve" << std::endl;
 48  std::cout << "Recognized options are:" << std::endl;
 49  std::cout << "  -W n\t\tuse grid width n" << std::endl;
 50  std::cout << "  -H n\t\tuse grid height n" << std::endl;
 51  std::cout << "  -r\t\toptimize over rotations" << std::endl;
 52  std::cout << "  -p\t\tsample point matrices in file1 and file2 " 
 53               "are in point-per-column ordering" << std::endl;
 54  std::cout << "  -o outfile\twrite matches to outfile" << std::endl;
 55  std::cout << "  -h\t\tshow this message" << std::endl;
 56}
 57
 58int main( int argc, char **argv ){
 59  size_t grid_width = DEFAULT_GRID_WIDTH;
 60  size_t grid_height = DEFAULT_GRID_HEIGHT;
 61  bool do_rotations = false;
 62  double salukwadze_weight = 1.0;
 63  const char *output_filename = "matches.mat";
 64  srvf::Pointset::PackingMethod packing = srvf::Pointset::POINT_PER_ROW;
 65  int opt;
 66
 67  while( (opt=getopt(argc, argv, "W:H:rw:po:h")) != -1 ){
 68    switch( opt ){
 69      case 'W':
 70        grid_width = atoi(optarg);
 71        break;
 72      case 'H':
 73        grid_height = atoi(optarg);
 74        break;
 75      case 'r':
 76        do_rotations = true;
 77        break;
 78      case 'w':  // shape distance weight for Salukwadze distance
 79        salukwadze_weight = atof(optarg);
 80        break;
 81      case 'p':  // sample point matrix = point per column
 82        packing = srvf::Pointset::POINT_PER_COLUMN;
 83        break;
 84      case 'o':
 85        output_filename = optarg;
 86        break;
 87      case 'h':
 88        do_usage(argv[0]);
 89        return 0;
 90      case '?':
 91        do_usage(argv[0]);
 92        return -1;
 93    }
 94  }
 95  if (argc - optind != 2) {
 96    do_usage(argv[0]);
 97    return -1;
 98  }
 99
100  std::ifstream ifs1(argv[optind]);
101  std::ifstream ifs2(argv[optind+1]);
102
103  std::vector<srvf::Matrix> F1data = srvf::io::load_csv ( ifs1, ' ', '\n' );
104  std::vector<srvf::Matrix> F2data = srvf::io::load_csv ( ifs2, ' ', '\n' );
105
106  ifs1.close();
107  ifs2.close();
108
109  if (F1data.size() == 0)
110  {
111    std::cerr << "Failed to load matrix from " << argv[optind]
112              << "; exiting." << std::endl;
113    return -1;
114  }
115  if (F2data.size() == 0)
116  {
117    std::cerr << "Failed to load matrix from " << argv[optind+1]
118              << "; exiting." << std::endl;
119    return -1;
120  }
121
122  srvf::Pointset F1samps(F1data[0], packing);
123  srvf::Pointset F2samps(F2data[0], packing);
124
125  srvf::Plf F1(F1samps);
126  srvf::Plf F2(F2samps);
127
128  std::cout << "F1 has " << F1.ncp() << " changepoints" << std::endl;
129  std::cout << "F2 has " << F2.ncp() << " changepoints" << std::endl;
130
131  if (F1.dim() != 2 && F1.dim() != 3)
132  {
133    std::cerr << "Invalid dimension: curves must have dimension 2 or 3." 
134              << std::endl;
135    return -1;
136  }
137  if (F1.dim() != F2.dim())
138  {
139    std::cerr << "F1 and F2 have different dimensions." << std::endl;
140    return -1;
141  }
142
143  double L1 = F1.arc_length();
144  double L2 = F2.arc_length();
145  double L = std::min(L1, L2);
146  F1.scale( 1.0 / L );
147  F2.scale( 1.0 / L );
148
149  srvf::Srvf Q1 = srvf::plf_to_srvf(F1);
150  srvf::Srvf Q2 = srvf::plf_to_srvf(F2);
151
152  srvf::pmatch::ParetoSet S = srvf::pmatch::find_matches (
153    Q1, Q2, do_rotations, grid_width, grid_height);
154
155  std::vector<double> reg_errs = S.regression_errors();
156  for (size_t i=0; i<reg_errs.size(); ++i)
157  {
158    if (S[i].empty()) continue;
159
160    std::cout << S[i][0].length() << " "
161              << reg_errs[i] << std::endl;
162  }
163
164  std::ofstream ofs(output_filename);
165  ofs << "# srvf_pmatch output" << std::endl;
166  ofs << "# File 1: " << argv[optind] << std::endl;
167  ofs << "# File 2: " << argv[optind+1] << std::endl;
168  ofs << "# Salukwadze dist: " 
169      << S.salukwadze_dist(salukwadze_weight) 
170      << std::endl << std::endl;
171
172  ofs << "# name: salukwadze_dist" << std::endl;
173  ofs << "# type: matrix" << std::endl;
174  ofs << "# rows: 1" << std::endl;
175  ofs << "# columns: 1" << std::endl;
176  ofs << S.salukwadze_dist(salukwadze_weight) 
177      << std::endl << std::endl;
178
179  ofs << "# name: pareto_set" << std::endl;
180  ofs << "# type: matrix" << std::endl;
181  ofs << "# rows: " << S.total_size() << std::endl;
182  ofs << "# columns: 5" << std::endl;
183  for (size_t i=0; i<S.nbuckets(); ++i)
184  {
185    for (size_t j=0; j<S[i].size(); ++j)
186    {
187      ofs << S[i][j].a << " " << S[i][j].b << " " 
188          << S[i][j].c << " " << S[i][j].d << " "
189          << S[i][j].dist << std::endl;
190    }
191  }
192  ofs.close();
193
194  srvf::plot::Plot *plot = NULL;
195  if (F1.dim() == 2)
196    plot = new srvf::plot::Plot2D();
197  else // dim = 3
198    plot = new srvf::plot::Plot3D();
199
200  plot->insert(F1, srvf::plot::Color(0.0, 0.0, 1.0), 2.0);
201  plot->insert(F2, srvf::plot::Color(1.0, 0.0, 0.0), 2.0);
202
203  UserInterface ui;
204
205  Fl_Window *win = ui.make_window();
206  ui.match_view->do_rotations(do_rotations);
207  ui.match_view->set_plot(plot);
208  ui.match_view->set_matches(S);
209  ui.slider_match_length->range(0.0, (double)(S.nbuckets()-1));
210  ui.slider_match_length->step(1.0);
211  ui.slider_match_length->value((double)(S.nbuckets()-1));
212  ui.set_match();
213
214  win->show();
215  Fl::run();
216
217  delete plot;
218  return 0;
219}
220