00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include <cvd/image_io.h>
00021 #include <cvd/vector_image_ref.h>
00022 #include <tag/printf.h>
00023 #include <tag/array.h>
00024 #include <TooN/TooN.h>
00025 #include <TooN/LU.h>
00026 #include <TooN/helpers.h>
00027
00028 #include <cstdlib>
00029
00030 #include "load_data.h"
00031 #include "warp_to_png.h"
00032 #include "utility.h"
00033
00034
00035 using namespace std;
00036 using namespace CVD;
00037 using namespace tag;
00038 using namespace TooN;
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049 vector<Image<byte> > load_images_cambridge(string dir, int n, string suffix)
00050 {
00051 dir += "/frames/frame_%i." + suffix;
00052
00053 vector<Image<byte> > ret;
00054
00055 for(int i=0; i < n; i++)
00056 {
00057 Image<byte> im;
00058 im = img_load(sPrintf(dir, i));
00059 ret.push_back(im);
00060 }
00061
00062 return ret;
00063 }
00064
00065
00066
00067
00068
00069
00070
00071
00072 vector<Image<byte> > load_images_vgg(string dir, int n)
00073 {
00074 dir += "/img%i.ppm";
00075
00076 vector<Image<byte> > ret;
00077
00078 for(int i=0; i < n; i++)
00079 ret.push_back(img_load(sPrintf(dir, i+1)));
00080
00081 return ret;
00082 }
00083
00084
00085
00086
00087
00088 istream& operator>>(istream& i, array<float, 2>& f)
00089 {
00090 i >> f[0] >> f[1];
00091 return i;
00092 }
00093
00094
00095
00096
00097 array<float, 2> Arr(const Vector<2>& vec)
00098 {
00099 return array<float, 2>((TupleHead, vec[0], vec[1]));
00100 }
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113 vector<vector<Image<array<float,2> > > > load_warps_cambridge_png(string dir, int num, ImageRef size)
00114 {
00115 dir += "/pngwarps/warp_%i_%i.png";
00116
00117 vector<vector<Image<array<float, 2> > > > ret(num, vector<Image<array<float, 2> > >(num));
00118
00119 BasicImage<byte> tester(NULL, size);
00120
00121 array<float, 2> outside((TupleHead, -1, -1));
00122
00123 for(int from = 0; from < num; from ++)
00124 for(int to = 0; to < num; to ++)
00125 if(from != to)
00126 {
00127 string fname = sPrintf(dir, from, to);
00128 Image<Rgb<unsigned short> > p = img_load(fname);
00129
00130 if(p.size() != size)
00131 {
00132 cerr << "Error: warp file " << fname << " is the wrong size!\n";
00133 exit(1);
00134 }
00135
00136 Image<array<float,2> > w(size, outside);
00137
00138 for(int y=0; y < size.y; y++)
00139 for(int x=0; x < size.x; x++)
00140 {
00141 w[y][x][0] = p[y][x].red / MULTIPLIER - SHIFT;
00142 w[y][x][1] = p[y][x].green / MULTIPLIER - SHIFT;
00143 }
00144
00145
00146 cerr << "Loaded " << fname << endl;
00147
00148 ret[from][to] = w;
00149 }
00150
00151 return ret;
00152 }
00153
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166
00167
00168 vector<vector<Image<array<float,2> > > > load_warps_cambridge(string dir, int num, ImageRef size)
00169 {
00170 dir += "/warps/warp_%i_%i.warp";
00171
00172 vector<vector<Image<array<float, 2> > > > ret(num, vector<Image<array<float, 2> > >(num));
00173
00174 BasicImage<byte> tester(NULL, size);
00175
00176 array<float, 2> outside((TupleHead, -1, -1));
00177
00178 for(int from = 0; from < num; from ++)
00179 for(int to = 0; to < num; to ++)
00180 if(from != to)
00181 {
00182 Image<array<float,2> > w(size, outside);
00183 int n = size.x * size.y;
00184 Image<array<float,2> >::iterator p = w.begin();
00185
00186 ifstream f;
00187 string fname = sPrintf(dir, from, to);
00188 f.open(fname.c_str());
00189
00190 if(!f.good())
00191 {
00192 cerr << "Error: " << fname << ": " << strerror(errno) << endl;
00193 exit(1);
00194 }
00195
00196 array<float, 2> v;
00197
00198 for(int i=0; i < n; ++i, ++p)
00199 {
00200 f >> v;
00201
00202
00203 *p = v;
00204 }
00205
00206 if(!f.good())
00207 {
00208 cerr << "Error: " << fname << " went bad" << endl;
00209 exit(1);
00210 }
00211
00212 cerr << "Loaded " << fname << endl;
00213
00214 ret[from][to] = w;
00215 }
00216
00217 return ret;
00218 }
00219
00220
00221
00222
00223 Matrix<3> invert(const Matrix<3>& m)
00224 {
00225 LU<3> i(m);
00226 return i.get_inverse();
00227 }
00228
00229
00230
00231
00232
00233
00234
00235
00236
00237
00238 vector<vector<Image<array<float, 2> > > > load_warps_vgg(string dir, int num, ImageRef size)
00239 {
00240 dir += "/H1to%ip";
00241 array<float, 2> outside((TupleHead, -1, -1));
00242
00243
00244 vector<Matrix<3> > H_1_to_x;
00245
00246
00247 {
00248 Matrix<3> i;
00249 Identity(i);
00250 H_1_to_x.push_back(i);
00251 }
00252
00253 for(int i=2; i <= num; i++)
00254 {
00255 ifstream f;
00256 string fname = sPrintf(dir, i).c_str();
00257 f.open(fname.c_str());
00258
00259 Matrix<3> h;
00260 f >> h;
00261
00262 if(!f.good())
00263 {
00264 cerr << "Error: " << fname << " went bad" << endl;
00265 exit(1);
00266 }
00267
00268 H_1_to_x.push_back(h);
00269 }
00270
00271 vector<vector<Image<array<float, 2> > > > ret(num, vector<Image<array<float, 2> > >(num));
00272
00273
00274 for(int from = 0; from < num; from ++)
00275 for(int to = 0; to < num; to ++)
00276 if(from != to)
00277 {
00278 Matrix<3> from_to_one = invert(H_1_to_x[from]);
00279 Matrix<3> one_to_to = H_1_to_x[to];
00280 Matrix<3> from_to_to = one_to_to * from_to_one;
00281
00282 Image<array<float,2> > w(size, outside);
00283
00284 for(int y=0; y < size.y; y++)
00285 for(int x=0; x < size.x; x++)
00286 {
00287 Vector<2> p = project(from_to_to * Vector<3>((make_Vector, x, y, 1)));
00288
00289 if(p[0] >= 0 && p[1] >= 0 && p[0] <= size.x-1 && p[1] <= size.y-1)
00290 w[y][x] = Arr(p);
00291 }
00292
00293 ret[from][to] = w;
00294
00295 cerr << "Created warp " << from << " -> " << to << endl;
00296 }
00297
00298 return ret;
00299 }
00300
00301
00302 enum DataFormat
00303 {
00304 Cambridge,
00305 CambridgePNGWarp,
00306 VGG
00307 };
00308
00309
00310
00311
00312
00313
00314
00315
00316 pair<vector<Image<byte> >, vector<vector<Image<array<float, 2> > > > > load_data(string dir, int num, string format)
00317 {
00318 vector<Image<byte> > images;
00319 vector<vector<Image<array<float, 2> > > > warps;
00320
00321 DataFormat d;
00322
00323 if(format == "vgg")
00324 d = VGG;
00325 else if(format == "cam-png")
00326 d = CambridgePNGWarp;
00327 else
00328 d = Cambridge;
00329
00330 switch(d)
00331 {
00332 case Cambridge:
00333 images = load_images_cambridge(dir, num, "pgm");
00334 break;
00335
00336 case CambridgePNGWarp:
00337 images = load_images_cambridge(dir, num, "png");
00338 break;
00339
00340 case VGG:
00341 images = load_images_vgg(dir, num);
00342 };
00343
00344
00345 if(images.size() == 0)
00346 {
00347 cerr << "No images!\n";
00348 exit(1);
00349 }
00350
00351 for(unsigned int i=0; i < images.size(); i++)
00352 if(images[i].size() != images[0].size())
00353 {
00354 cerr << "Images are different sizes!\n";
00355 exit(1);
00356 }
00357
00358 switch(d)
00359 {
00360 case CambridgePNGWarp:
00361 warps = load_warps_cambridge_png(dir, num, images[0].size());
00362 break;
00363
00364 case Cambridge:
00365 warps = load_warps_cambridge(dir, num, images[0].size());
00366 break;
00367
00368 case VGG:
00369 warps = load_warps_vgg(dir, num, images[0].size());
00370 };
00371
00372
00373 return make_pair(images, warps);
00374 }
00375
00376
00377
00378
00379
00380
00381
00382
00383
00384 void prune_warps(vector<vector<Image<array<float, 2> > > >& warps, ImageRef size)
00385 {
00386 BasicImage<byte> test(NULL, size);
00387 array<float, 2> outside = make_tuple(-1, -1);
00388
00389 for(unsigned int i=0; i < warps.size(); i++)
00390 for(unsigned int j=0; j < warps[i].size(); j++)
00391 {
00392 for(Image<array<float, 2> >::iterator p=warps[i][j].begin(); p != warps[i][j].end(); p++)
00393 if(!test.in_image(ir_rounded(*p)))
00394 *p = outside;
00395 }
00396 }
00397
00398
00399