1 #include <string>
2 #include <vector>
3 #include <iostream>
4 #include <cstdio>
5 #ifdef _MSC_VER
6 #  include "vcl_msvc_warnings.h"
7 #endif
8 #include "vbl/vbl_bounding_box.h"
9 #include "vul/vul_sprintf.h"
10 #include "vul/vul_file.h"
11 #include "vul/vul_file_iterator.h"
12 #include "vnl/vnl_matrix.h"
13 #include "vil/vil_load.h"
14 #include "vil/vil_save.h"
15 #include "vil/vil_image_resource.h"
16 #include "vil/vil_image_view.h"
17 #include "vil/vil_convert.h"
18 #include <ihog/ihog_minimizer.h>
19 #include <ihog/ihog_world_roi.h>
20 #include <ihog/ihog_transform_2d.h>
21 #include <ihog/ihog_transform_2d_sptr.h>
22 #include <ihog/ihog_sample_grid_bilin.h>
23 
24 
filenames_from_directory(std::string const & dirname,std::vector<std::string> & filenames)25 static void filenames_from_directory(std::string const& dirname,
26                                      std::vector<std::string>& filenames)
27 {
28   std::string s(dirname);
29   s += "/*.*";
30   for (vul_file_iterator fit = s;fit; ++fit) {
31     // check to see if file is a directory.
32     if (vul_file::is_directory(fit()))
33       continue;
34     filenames.emplace_back(fit());
35   }
36 }
37 
read_homographies(std::string const & filename,std::vector<vnl_matrix<double>> & homographies)38 static bool read_homographies(std::string const& filename, std::vector<vnl_matrix<double> >& homographies)
39 {
40   std::ifstream ifile(filename.c_str(),std::ios::in);
41   std::cout<<"\n Reading Homographies "<<filename;
42 
43   if (!ifile)
44   {
45     std::cout<<"\n error opening file";
46     std::cout.flush();
47     return false;
48   }
49   char buffer[100];
50   while (ifile.getline(buffer,100))
51   {
52     vnl_matrix<double> p(3,3);
53     ifile>>p;
54     std::cout<<p;
55     homographies.push_back(p);
56     ifile.getline(buffer,100);
57   }
58   std::cout.flush();
59   return true;
60 }
61 
register_images(std::string const & homography_file,std::string const & image_indir,std::string const & image_outdir)62 static bool register_images(std::string const& homography_file,
63                             std::string const& image_indir,
64                             std::string const& image_outdir)
65 {
66   int bimg_ni;
67   int bimg_nj;
68 
69   int offset_i;
70   int offset_j;
71 
72   vbl_bounding_box<double,2> box;
73   std::vector<vnl_matrix<double> > homographies;
74   read_homographies(homography_file, homographies);
75   unsigned nframes = homographies.size();
76   if (!nframes)
77   {
78     std::cout << "no transforms to use in registration\n";
79     return false;
80   }
81   std::vector<std::string> in_filenames;
82   filenames_from_directory(image_indir, in_filenames);
83   unsigned n_infiles = in_filenames.size();
84   unsigned infile_counter = 0;
85   //read the first image
86   bool no_valid_image = true;
87   vil_image_resource_sptr imgr;
88   while (no_valid_image)
89   {
90     imgr =
91       vil_load_image_resource(in_filenames[infile_counter++].c_str());
92     no_valid_image = !imgr||imgr->ni()==0||imgr->nj()==0;
93     if (infile_counter>=n_infiles)
94       return false;
95   }
96   unsigned ni =  imgr->ni(), nj =  imgr->nj();
97   infile_counter = 0;//return to first frame
98 
99   std::vector<ihog_transform_2d > xforms;
100   for (unsigned i=0;i<nframes;i++)
101   {
102     ihog_transform_2d p;
103     vnl_double_2x3 M23(homographies[i][0][0],homographies[i][0][1],homographies[i][0][2],
104                        homographies[i][1][0],homographies[i][1][1],homographies[i][1][2]);
105     p.set_affine(M23);
106     xforms.push_back(p);
107     box.update(p(0,0).x(),p(0,0).y());
108     box.update(p(0,nj).x(),p(0,nj).y());
109     box.update(p(ni,0).x(),p(ni,0).y());
110     box.update(p(ni,nj).x(),p(ni,nj).y());
111   }
112 
113   bimg_ni=(int)std::ceil(box.max()[0]-box.min()[0]);
114   bimg_nj=(int)std::ceil(box.max()[1]-box.min()[1]);
115 
116   offset_i=(int)std::ceil(0-box.min()[0]);
117   offset_j=(int)std::ceil(0-box.min()[1]);
118 
119   std::string outfile = image_outdir + "/reg";
120 
121   for (unsigned frame = 0;frame<nframes; ++frame)
122   {
123     no_valid_image = true;
124     while (no_valid_image)
125     {
126       imgr =
127         vil_load_image_resource(in_filenames[infile_counter++].c_str());
128       no_valid_image = !imgr||imgr->ni()==0||imgr->nj()==0;
129       if (infile_counter>=n_infiles)
130       {
131         std::cout << "Number of homographies and input images do not match\n";
132         return false;
133       }
134     }
135     vil_image_view<float> curr_view =
136       *vil_convert_cast(float(), imgr->get_view());
137     ihog_transform_2d ftxform=xforms[frame].inverse();
138     ihog_image<float> sample_im;
139 
140     vgl_point_2d<double> p(-offset_i,-offset_j);
141     vgl_vector_2d<double> u(1,0);
142     vgl_vector_2d<double> v(0,1);
143 
144     ihog_image<float> curr_img(curr_view,ftxform);
145     ihog_resample_bilin(curr_img,sample_im,p,u,v,bimg_ni,bimg_nj);
146 
147     vil_image_view<vxl_byte> temp;
148     vil_convert_stretch_range(sample_im.image(), temp);
149     std::string outname = vul_sprintf("%s%05d.%s", outfile.c_str(),
150                                      frame,
151                                      "tif");
152     vil_save(temp, outname.c_str());
153   }
154   return false;
155 }
156 
main(int argc,char * argv[])157 int main(int argc,char * argv[])
158 {
159   if (argc!=4)
160   {
161     std::cout<<"Usage : register_images.exe homography_file image_in_dir image_out_dir\n";
162     return -1;
163   }
164   else
165   {
166     std::string homography_name(argv[1]);
167     std::string image_indir(argv[2]);
168     std::string image_outdir(argv[3]);
169     if (!register_images(homography_name, image_indir, image_outdir))
170     {
171       std::cout << "Registration failed\n";
172       return -1;
173     }
174     else
175       return 0;
176   }
177 }
178