1 // This is brl/bpro/core/vpgl_pro/processes/vpgl_compute_affine_from_rational_process.cxx
2 //:
3 // \file
4 // \brief A process for computing an affine camera approximation of a "local" rational camera.
5 //        i.e. use case: create a bvxm/boxm2 scene, crop a satellite image using the scene and create a "local" rational camera (cropped camera) using its local bounding box in 3d
6 //        The process samples random points from the input bounding box
7 //        projects these points into the image using local rational camera to find image points of these 3d points
8 //        then uses vpgl_affine_camera_compute to fit an affine camera to these projections
9 //        the output affine camera is in the local vertical coordinte system given by the LVCS of the local rational camera
10 // \author Ozge C. Ozcanli
11 // \date Nov 26, 2013
12 
13 #include <bprb/bprb_func_process.h>
14 #include <bprb/bprb_parameters.h>
15 #include <brdb/brdb_value.h>
16 #include <vpgl/algo/vpgl_camera_convert.h>
17 #include <vpgl/algo/vpgl_affine_rectification.h>
18 #include "vpgl/vpgl_local_rational_camera.h"
19 #include "vnl/vnl_random.h"
20 #include "vgl/vgl_box_3d.h"
21 
vpgl_compute_affine_from_rat_process_cons(bprb_func_process & pro)22 bool vpgl_compute_affine_from_rat_process_cons(bprb_func_process& pro)
23 {
24   //set output types
25   std::vector<std::string> input_types_(8);
26   int i=0;
27   input_types_[i++] = "vpgl_camera_double_sptr";  // camera  -- pass local rational camera
28   input_types_[i++] = "double";    // min point x (e.g. lower left corner of a scene bbox)
29   input_types_[i++] = "double";    // min point y
30   input_types_[i++] = "double";    // min point z
31   input_types_[i++] = "double";    // max point x (e.g. upper right corner of a scene bbox)
32   input_types_[i++] = "double";    // max point y
33   input_types_[i++] = "double";    // max point z
34   input_types_[i++] = "unsigned";    // n_points -- randomly sample this many points form the voxel volume, e.g. 100
35   if (!pro.set_input_types(input_types_))
36     return false;
37   std::vector<std::string> output_types_(1);
38   output_types_[0] = "vpgl_camera_double_sptr";  // output affine camera
39   return pro.set_output_types(output_types_);
40 }
41 
vpgl_compute_affine_from_rat_process(bprb_func_process & pro)42 bool vpgl_compute_affine_from_rat_process(bprb_func_process& pro)
43 {
44   unsigned i = 0;
45   vpgl_camera_double_sptr camera = pro.get_input<vpgl_camera_double_sptr>(i++);
46   auto min_x = pro.get_input<double>(i++);
47   auto min_y = pro.get_input<double>(i++);
48   auto min_z = pro.get_input<double>(i++);
49   auto max_x = pro.get_input<double>(i++);
50   auto max_y = pro.get_input<double>(i++);
51   auto max_z = pro.get_input<double>(i++);
52   auto n_points = pro.get_input<unsigned>(i++);
53   if (n_points <= 3)
54     n_points = 10;   // make it minimum 10 points
55 
56   if (!camera) {
57     std::cout << pro.name() <<" :--  Input 0  is not valid!\n";
58     return false;
59   }
60   auto* rat_camera = dynamic_cast<vpgl_local_rational_camera<double>*> (camera.as_pointer());
61   if (!rat_camera) {
62     std::cout << pro.name() <<" :--  Input camera is not a local rational camera!\n";
63     return false;
64   }
65 
66   vgl_point_3d<double> pmin(min_x, min_y, min_z);
67   vgl_point_3d<double> pmax(max_x, max_y, max_z);
68   vgl_box_3d<double> bb;
69   bb.add(pmin); bb.add(pmax);
70 
71   vpgl_affine_camera<double>* acam_ptr = new vpgl_affine_camera<double>;
72   bool good = vpgl_affine_camera_convert::convert(*rat_camera, bb, *acam_ptr, n_points);
73   if(!good)
74     return false;
75 
76   pro.set_output_val<vpgl_camera_double_sptr>(0, acam_ptr);
77   return true;
78 }
79