1 #include "testlib/testlib_test.h"
2 #include "vul/vul_file.h"
3 
4 #include "vgl/vgl_point_3d.h"
5 #include "vgl/vgl_vector_3d.h"
6 #include <vgl/algo/vgl_rotation_3d.h>
7 
8 #include <bvxm/bvxm_voxel_world.h>
9 #include <bvxm/bvxm_world_params.h>
10 #include <bvxm/bvxm_mog_grey_processor.h>
11 #include "vil/vil_math.h"
12 #include "vil/vil_load.h"
13 #include "vil/vil_image_view.h"
14 #include "vpgl/vpgl_perspective_camera.h"
15 #include "vpl/vpl.h"
16 
17 
test_voxel_world_mog_image()18 static void test_voxel_world_mog_image()
19 {
20   std::string model_dir("test_world_dir");
21   if (vul_file::is_directory(model_dir))
22     vpl_rmdir(model_dir.c_str());
23   else if (vul_file::exists(model_dir))
24       vpl_unlink(model_dir.c_str());
25   vul_file::make_directory(model_dir);
26 
27 
28   unsigned nx = 200;
29   unsigned ny = 200;
30   unsigned nz = 4;
31   vgl_point_3d<float> corner(0.f,0.f,0.f);
32   vgl_vector_3d<unsigned> num_voxels(nx,ny,nz);
33   float voxel_length = 1.0f;
34   unsigned scale=0;
35 
36   // create a synthetic world
37   bvxm_world_params_sptr params = new bvxm_world_params();
38   params->set_params(model_dir, corner, num_voxels, voxel_length);
39   bvxm_voxel_world_sptr vox_world = new bvxm_voxel_world(params);
40 
41   bvxm_voxel_grid_base_sptr ocp_grid_ptr = vox_world->get_grid<OCCUPANCY>(0,scale);
42   auto *ocp_grid = dynamic_cast<bvxm_voxel_grid<float>*>(ocp_grid_ptr.ptr());
43   // fill in grid with zeros to start
44   ocp_grid->initialize_data(0.0f);
45   // now make a ground plane
46   bvxm_voxel_grid<float>::iterator ocp_it = ocp_grid->slab_iterator(nz-1);
47   (*ocp_it).fill(1.0f);
48   // data not written to disk until iterator is iterated
49   ++ocp_it;
50 
51   // create a synthetic image to fill layers with
52   bvxm_voxel_slab<float> plane_img(nx,ny,1);
53   for (unsigned i=0; i<nx; ++i) {
54     for (unsigned j=0; j<ny; ++j) {
55       // mark the origin/x axis
56       if ( (i < 20) && (j < 5) ) {
57         plane_img(i,j) = 0.2f;
58       }
59       // just make some squares of constant color
60       else if ( (i > 10) && (i < 90) && (j > 10) && (j < 90) ) {
61         plane_img(i,j) = 0.7f;
62       }
63       else if ((i > 110) && (i < 190) && (j > 10) && (j < 90) ) {
64         plane_img(i,j) = 0.5f;
65       }
66       else if ((i > 10) && (i < 90) && (j > 110) && (j < 190) ) {
67         plane_img(i,j) = 0.3f;
68       }
69       else if ((i > 110) && (i < 190) && (j > 110) && (j < 190) ) {
70         plane_img(i,j) = 0.1f;
71       }
72       else {
73         plane_img(i,j) = 1.0;
74       }
75 #if 0
76       plane_img(i,j) = plane_img(i,j) + ((0.2f*i)/(float)nx + (0.2f*j)/(float)ny);
77 #endif
78     }
79   }
80   typedef bvxm_voxel_traits<APM_MOG_GREY>::voxel_datatype mog_type;
81 
82   bvxm_voxel_traits<APM_MOG_GREY>::appearance_processor apm_processor;
83 
84   // create a slab of constant weights for update
85   bvxm_voxel_slab<float> ones(nx,ny,1);
86   ones.fill(1.0f);
87 
88   // iterate through layers of apm grid and update each level with the same synthetic image
89   // if you want different levels to look different youll have to create a different image for each level
90   bvxm_voxel_grid_base_sptr apm_base = vox_world->get_grid<APM_MOG_GREY>(0,scale);
91   auto *apm_grid = dynamic_cast<bvxm_voxel_grid<mog_type>*>(apm_base.ptr());
92   // initialize the appearance model data to get rid of any previous data on disk
93   apm_grid->initialize_data(bvxm_voxel_traits<APM_MOG_GREY>::initial_val());
94 
95   bvxm_voxel_grid<mog_type>::iterator apm_it = apm_grid->begin();
96   for (; apm_it != apm_grid->end(); ++apm_it) {
97     apm_processor.update(*apm_it, plane_img, ones);
98   }
99 
100   // now create a couple of cameras and generate the expected images
101   vnl_matrix_fixed<double,3,3> K(0.0);
102   double f = 550.0;
103   double offx = 320.0;
104   double offy = 240.0;
105   K(0,0) = f; K(1,1) = f;
106   K(0,2) = offx; K(1,2) = offy;
107   K(2,2) = 1.0;
108   vgl_point_3d<double> center1(100,-100,275);
109   vgl_rotation_3d<double> rot1(5*vnl_math::pi/6,0.0,0.0);
110 
111   vpgl_camera_double_sptr cam1 = new vpgl_perspective_camera<double>(K,center1,rot1);
112   bvxm_image_metadata meta1(vil_image_view_base_sptr(nullptr),cam1);
113   vil_image_view<float> mask(640,480,1);
114   vil_image_view_base_sptr img1 = new vil_image_view<unsigned char>(640,480);
115 
116   vox_world->expected_image<APM_MOG_GREY>(meta1,img1,mask);
117 
118   // debug: write out images
119   vil_save(*img1,"./expected1.png");
120 
121   bvxm_image_metadata meta2(img1,cam1);
122 
123   bvxm_voxel_slab_base_sptr mog_image;
124   TEST("testing mixture of gaussian image creation", vox_world->mixture_of_gaussians_image<APM_MOG_GREY>(meta2, mog_image, 0), true);
125   TEST("testing mixture of gaussian image creation", !mog_image, false);
126 
127   auto* mog_image_ptr = dynamic_cast<bvxm_voxel_slab<mog_type>*>(mog_image.ptr());
128   TEST("testing mixture of gaussian image creation", !mog_image_ptr, false);
129 
130   bvxm_voxel_slab<float> prob = apm_processor.expected_color(*mog_image_ptr);
131 
132   vil_image_view_base_sptr expected_img = new vil_image_view<vxl_byte>(640,480,1);
133   bvxm_util::slab_to_img(prob, expected_img);
134   vil_save(*expected_img,"./expected2.png");
135 
136   // we want the two expected images to be exactly the same
137   vil_image_view<float> im_dif;
138   vil_image_view<vxl_byte> expected_img_r(*expected_img);
139   vil_image_view<vxl_byte> img1_r(*img1);
140   vil_math_image_difference(expected_img_r, img1_r, im_dif);
141   float sum;
142   vil_math_sum(sum, im_dif, 0);
143   // MAY NEED FIX -- The two expected images differ only by their initial values.  Other than that, the rendered results are same
144   //TEST_NEAR("image dif should sum to 0", sum, 0.0f, 5.0f);  // imgs look exactly the same but there is dif of 4
145 
146   bvxm_voxel_slab_base_sptr mog_image2;
147   TEST("testing mixture of gaussian image creation with samplling", vox_world->mog_image_with_random_order_sampling<APM_MOG_GREY>(meta2, 10, mog_image2, 0), true);
148   TEST("testing mixture of gaussian image creation with sampling", !mog_image2, false);
149 
150   mog_image_ptr = dynamic_cast<bvxm_voxel_slab<mog_type>*>(mog_image2.ptr());
151   TEST("testing mixture of gaussian image creation with sampling", !mog_image_ptr, false);
152 
153   bvxm_voxel_slab<float> prob2 = apm_processor.expected_color(*mog_image_ptr);
154 
155   vil_image_view_base_sptr expected_img2 = new vil_image_view<vxl_byte>(640,480,1);
156   bvxm_util::slab_to_img(prob2, expected_img2);
157   vil_save(*expected_img2,"./expected3.png");
158 
159 
160 #if 0
161   // create an existing voxel world
162   bvxm_world_params_sptr params3 = new bvxm_world_params();
163   bgeo_lvcs_sptr lvcs = new bgeo_lvcs();
164   params3->set_params("D:\\projects\\change\\plasticville\\world_dir",
165                       vgl_point_3d<float> (-10.0f, -10.0f, -5.0f),
166                       vgl_vector_3d<unsigned int> (400, 400, 80),
167                       0.27f, lvcs, 0.001f, 0.99f, 1);
168   bvxm_voxel_world_sptr vox_world2 = new bvxm_voxel_world;
169   vox_world2->set_params(params3);
170   // load a test image and camera
171   std::string image_fname = "D:/projects/change/plasticville/outseq/DSCN0521.jpg";
172   std::string camera_fname = "D:/projects/change/plasticville/outseq_cams/frame_00.txt";
173   vil_image_view_base_sptr img3 = vil_load(image_fname.c_str());
174   // read projection matrix from the file.
175   std::ifstream ifs(camera_fname.c_str());
176   vnl_matrix_fixed<double,3,4> projection_matrix; ifs >> projection_matrix;
177   vbl_smart_ptr<vpgl_camera<double> > procam3 = new vpgl_proj_camera<double>(projection_matrix);
178   bvxm_image_metadata meta3(img3,procam3);
179 
180   bvxm_voxel_slab_base_sptr mog_image2;
181   TEST("testing mixture of gaussian image with sampling", vox_world2->mog_image_with_random_order_sampling<APM_MOG_GREY>(meta3, 5, mog_image2, 0, 0), true);
182 #endif
183 }
184 
185 TESTMAIN( test_voxel_world_mog_image );
186