/demos/pmatch-gui/src/main.cc
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