00001 #include <vcl_cstring.h>
00002
00003 #include <vgl/vgl_box_2d.h>
00004 #include <vgl/vgl_box_3d.h>
00005 #include <vgl/vgl_point_2d.h>
00006 #include <vgl/vgl_point_3d.h>
00007 #include <vsol/vsol_box_2d.h>
00008
00009 #include <vil/vil_load.h>
00010 #include <vil/vil_image_resource.h>
00011 #include <vil/file_formats/vil_tiff.h>
00012
00013 #include <bprb/bprb_parameters.h>
00014 #include <bprb/bprb_func_process.h>
00015
00016 #include <vpgl/vpgl_utm.h>
00017 #include <vpgl/vpgl_lvcs.h>
00018 #include <vpgl/file_formats/vpgl_geo_camera.h>
00019
00020 #include <brip/brip_roi.h>
00021 #include <brdb/brdb_value.h>
00022 #include <bmdl/bmdl_classify.h>
00023
00024 template<class T>
00025 vcl_vector<vgl_point_3d<T> > corners_of_box_3d(vgl_box_3d<T> box)
00026 {
00027 vcl_vector<vgl_point_3d<T> > corners;
00028
00029 corners.push_back(box.min_point());
00030 corners.push_back(vgl_point_3d<T> (box.min_x()+box.width(), box.min_y(), box.min_z()));
00031 corners.push_back(vgl_point_3d<T> (box.min_x()+box.width(), box.min_y()+box.height(), box.min_z()));
00032 corners.push_back(vgl_point_3d<T> (box.min_x(), box.min_y()+box.height(), box.min_z()));
00033 corners.push_back(vgl_point_3d<T> (box.min_x(), box.min_y(), box.max_z()));
00034 corners.push_back(vgl_point_3d<T> (box.min_x()+box.width(), box.min_y(), box.max_z()));
00035 corners.push_back(box.max_point());
00036 corners.push_back(vgl_point_3d<T> (box.min_x(), box.min_y()+box.height(), box.max_z()));
00037 return corners;
00038 }
00039
00040 bool compute_ground(vil_image_resource_sptr ground,
00041 vil_image_view_base_sptr first_roi,
00042 vil_image_view_base_sptr last_roi,
00043 vil_image_view_base_sptr& ground_roi)
00044 {
00045 if (ground == 0)
00046 {
00047 if ((first_roi->pixel_format() == VIL_PIXEL_FORMAT_FLOAT) &&
00048 (last_roi->pixel_format() == VIL_PIXEL_FORMAT_FLOAT)) {
00049 vil_image_view<float>* ground_view = new vil_image_view<float>();
00050 vil_image_view<float> first_view(first_roi);
00051 vil_image_view<float> last_view(last_roi);
00052 bmdl_classify<float> classifier;
00053 classifier.set_lidar_data(first_view, last_view);
00054 classifier.estimate_bare_earth();
00055 ground_view->deep_copy(classifier.bare_earth());
00056 ground_roi = ground_view;
00057 }
00058 else if ((first_roi->pixel_format() == VIL_PIXEL_FORMAT_DOUBLE) &&
00059 (last_roi->pixel_format() == VIL_PIXEL_FORMAT_DOUBLE)) {
00060 vil_image_view<double>* ground_view = new vil_image_view<double>();
00061 vil_image_view<double> first_view(first_roi);
00062 vil_image_view<double> last_view(last_roi);
00063 bmdl_classify<double> classifier;
00064 classifier.set_lidar_data(first_view, last_view);
00065 classifier.estimate_bare_earth();
00066 ground_view->deep_copy(classifier.bare_earth());
00067 ground_roi = ground_view;
00068 }
00069 else {
00070 vcl_cout << "input images have different bit depths" << vcl_endl;
00071 return false;
00072 }
00073 }
00074 return true;
00075 }
00076
00077
00078 bool lidar_roi(unsigned type,
00079 vil_image_resource_sptr lidar_first,
00080 vil_image_resource_sptr lidar_last,
00081 vil_image_resource_sptr ground,
00082 float min_lat, float min_lon,
00083 float max_lat, float max_lon,
00084 vil_image_view_base_sptr& first_roi,
00085 vil_image_view_base_sptr& last_roi,
00086 vil_image_view_base_sptr& ground_roi,
00087 vpgl_geo_camera*& camera)
00088 {
00089
00090 if (vcl_strcmp(lidar_first->file_format(), "tiff") != 0 &&
00091 vcl_strcmp(lidar_last->file_format(),"tiff") != 0) {
00092 vcl_cout << "bmdl_lidar_roi_process::lidar_roi -- The lidar images should be a TIFF!\n";
00093 return false;
00094 }
00095
00096 #if HAS_GEOTIFF
00097 vil_tiff_image* tiff_first = static_cast<vil_tiff_image*> (lidar_first.ptr());
00098 vil_tiff_image* tiff_last = static_cast<vil_tiff_image*> (lidar_last.ptr());
00099
00100 if (vpgl_geo_camera::init_geo_camera(tiff_first, 0, camera))
00101 {
00102 vgl_box_2d<double> roi_box;
00103
00104 if (type == 0)
00105 {
00106
00107 vgl_point_3d<double> min_pos(min_lon, min_lat, 0);
00108 vgl_point_3d<double> max_pos(max_lon, max_lat, 30);
00109 vgl_box_3d<double> world(min_pos, max_pos);
00110 vcl_vector<vgl_point_3d<double> > corners = corners_of_box_3d<double>(world);
00111 for (unsigned i=0; i<corners.size(); i++) {
00112 double x = corners[i].x();
00113 double y = corners[i].y();
00114 double z = corners[i].z();
00115 double lx, ly, lz;
00116 camera->lvcs()->global_to_local(x, y, z,vpgl_lvcs::wgs84, lx, ly, lz);
00117 double u,v;
00118 camera->project(lx,ly,lz,u,v);
00119 vgl_point_2d<double> p(u,v);
00120 roi_box.add(p);
00121 }
00122 }
00123 else if (type == 1) {
00124 roi_box.add(vgl_point_2d<double> (min_lat, min_lon));
00125 roi_box.add(vgl_point_2d<double> (max_lat, max_lon));
00126 }
00127
00128 brip_roi broi(tiff_first->ni(), tiff_first->nj());
00129 vsol_box_2d_sptr bb = new vsol_box_2d();
00130 bb->add_point(roi_box.min_x(), roi_box.min_y());
00131 bb->add_point(roi_box.max_x(), roi_box.max_y());
00132
00133 bb = broi.clip_to_image_bounds(bb);
00134
00135
00136 first_roi = tiff_first->get_copy_view((unsigned int)bb->get_min_x(),
00137 (unsigned int)bb->width(),
00138 (unsigned int)bb->get_min_y(),
00139 (unsigned int)bb->height());
00140
00141 last_roi = tiff_last->get_copy_view((unsigned int)bb->get_min_x(),
00142 (unsigned int)bb->width(),
00143 (unsigned int)bb->get_min_y(),
00144 (unsigned int)bb->height());
00145
00146
00147 if (ground == 0) {
00148 compute_ground(ground, first_roi, last_roi, ground_roi);
00149 }
00150 else {
00151 ground_roi = ground->get_copy_view((unsigned int)bb->get_min_x(),
00152 (unsigned int)bb->width(),
00153 (unsigned int)bb->get_min_y(),
00154 (unsigned int)bb->height());
00155 }
00156
00157
00158 double ox = bb->get_min_x();
00159 double oy = bb->get_min_y();
00160 double elev = 0;
00161 if (ground_roi->pixel_format() == VIL_PIXEL_FORMAT_FLOAT) {
00162 vil_image_view<float> ground_view(ground_roi);
00163 elev = ground_view(0,0);
00164 }
00165 else if (ground_roi->pixel_format() == VIL_PIXEL_FORMAT_DOUBLE) {
00166 vil_image_view<double> ground_view(ground_roi);
00167 elev = ground_view(0,0);
00168 }
00169 camera->translate(ox, oy, elev);
00170
00171 if (!first_roi) {
00172 vcl_cout << "bmdl_lidar_roi_process::lidar_init()-- clipping box is out of image boundaries\n";
00173 return false;
00174 }
00175 }
00176 else {
00177 vcl_cout << "bmdl_lidar_roi_process::lidar_init()-- Only ProjectedCSTypeGeoKey=PCS_WGS84_UTM_zoneXX_X is defined rigth now, please define yours!!" << vcl_endl;
00178 return false;
00179 }
00180
00181 return true;
00182 #else // if !HAS_GEOTIFF
00183 vcl_cout << "bmdl_lidar_roi_process::lidar_init()-- GEOTIFF lib is needed to run bmdl_lidar_roi_process--\n";
00184 return false;
00185 #endif // HAS_GEOTIFF
00186
00187 return true;
00188 }
00189
00190 bool bmdl_lidar_roi_process(bprb_func_process& pro)
00191 {
00192 if (pro.n_inputs()< 8) {
00193 vcl_cout << "lidar_roi_process: The input number should be 8" << vcl_endl;
00194 return false;
00195 }
00196
00197 unsigned int i=0;
00198 vcl_string first = pro.get_input<vcl_string>(i++);
00199 vcl_string last = pro.get_input<vcl_string>(i++);
00200 vcl_string ground = pro.get_input<vcl_string>(i++);
00201 float min_lat = pro.get_input<float>(i++);
00202 float min_lon = pro.get_input<float>(i++);
00203 float max_lat = pro.get_input<float>(i++);
00204 float max_lon = pro.get_input<float>(i++);
00205 unsigned type = pro.get_input<unsigned>(i++);
00206
00207
00208 vil_image_resource_sptr first_ret = vil_load_image_resource(first.c_str());
00209 if (!first_ret) {
00210 vcl_cout << "bmdl_lidar_roi_process -- First return image path is not valid!\n";
00211 return false;
00212 }
00213
00214
00215 vil_image_resource_sptr last_ret = vil_load_image_resource(last.c_str());
00216 if (!last_ret) {
00217 vcl_cout << "bmdl_lidar_roi_process -- Last return image path is not valid!\n";
00218 return false;
00219 }
00220
00221
00222 vil_image_resource_sptr ground_img =0;
00223 if (ground.size() > 0) {
00224 ground_img = vil_load_image_resource(ground.c_str());
00225 }
00226
00227 vil_image_view_base_sptr first_roi=0, last_roi=0, ground_roi;
00228 vpgl_geo_camera* lidar_cam =0;
00229 if (!lidar_roi(type, first_ret, last_ret, ground_img,
00230 min_lat, min_lon, max_lat, max_lon, first_roi, last_roi, ground_roi, lidar_cam)) {
00231 vcl_cout << "bmdl_lidar_roi_process -- The process has failed!\n";
00232 return false;
00233 }
00234
00235 unsigned j=0;
00236
00237 pro.set_output_val<vil_image_view_base_sptr>(j++, first_roi);
00238
00239
00240 pro.set_output_val<vil_image_view_base_sptr>(j++,last_roi);
00241
00242
00243 pro.set_output_val<vil_image_view_base_sptr>(j++,ground_roi);
00244
00245
00246 pro.set_output_val<vpgl_camera_double_sptr >(j++, lidar_cam);
00247
00248 return true;
00249 }
00250
00251 bool bmdl_lidar_roi_process_cons(bprb_func_process& pro)
00252 {
00253 bool ok=false;
00254 vcl_vector<vcl_string> input_types;
00255 input_types.push_back("vcl_string");
00256 input_types.push_back("vcl_string");
00257 input_types.push_back("vcl_string");
00258 input_types.push_back("float");
00259 input_types.push_back("float");
00260 input_types.push_back("float");
00261 input_types.push_back("float");
00262 input_types.push_back("unsigned");
00263 ok = pro.set_input_types(input_types);
00264 if (!ok) return ok;
00265
00266 vcl_vector<vcl_string> output_types;
00267 output_types.push_back("vil_image_view_base_sptr");
00268 output_types.push_back("vil_image_view_base_sptr");
00269 output_types.push_back("vil_image_view_base_sptr");
00270 output_types.push_back("vpgl_camera_double_sptr");
00271 ok = pro.set_output_types(output_types);
00272 if (!ok) return ok;
00273
00274 return true;
00275 }