1import brl_init 2import boxm2_batch as batch 3dbvalue = brl_init.register_batch(batch) 4 5import os 6import re 7import shutil 8import sys 9from xml.etree.ElementTree import ElementTree 10from os.path import basename, splitext 11 12import boxm2_adaptor 13import boxm2_tools_adaptor 14import boxm2_filtering_adaptor 15import vil_adaptor_boxm2_batch as vil_adaptor 16import vpgl_adaptor_boxm2_batch as vpgl_adaptor 17 18 19############################################################################# 20# boxm2_scene_adaptor class offers super simple model manipulation syntax 21# you can always force the process to use CPP by just passing in "cpp" as the last 22# arg to any function in this class 23############################################################################# 24 25 26class boxm2_scene_adaptor(object): 27 28 # scene adaptor init 29 def __init__(self, scene_str, device_string="gpu", 30 opencl_multi_scene_cache=False): 31 32 # init (list) self vars 33 self.scene = None 34 self.active_cache = None 35 self.device_string = None 36 self.cpu_cache = None 37 self.device = None 38 self.opencl_cache = None 39 self.str_cache = None 40 self.model_dir = None 41 self.bbox = None 42 self.lvcs = None 43 44 # if device_string is gpu, load up opencl 45 self.device_string = device_string 46 if device_string[0:3] == "gpu" or device_string[0:3] == "cpu": 47 self.scene, self.cpu_cache, self.device, self.opencl_cache = \ 48 boxm2_adaptor.load_opencl(scene_str, device_string) 49 self.active_cache = self.opencl_cache 50 elif device_string[0:3] == "cpp": 51 self.scene, self.cpu_cache = boxm2_adaptor.load_cpp(scene_str) 52 self.active_cache = self.cpu_cache 53 else: 54 print "UNKNOWN device type: ", device_string 55 print "exiting." 56 exit(-1) 57 # store model directory for later use 58 self.bbox = boxm2_adaptor.scene_bbox(self.scene) 59 self.description = boxm2_adaptor.describe_scene(self.scene) 60 self.model_dir = self.description['dataPath'] 61 # stores whether appearance model contains RGB - also includes view_dep 62 self.rgb = self.description['appType'] == "boxm2_gauss_rgb" 63 self.lvcs = boxm2_adaptor.scene_lvcs(self.scene) 64 self.view = ("view" in self.description['appType']) 65 66 def __del__(self): 67 if self.scene is not None: 68 batch.remove_data(self.scene.id) 69 if self.cpu_cache is not None: 70 batch.remove_data(self.cpu_cache.id) 71 if self.device is not None: 72 batch.remove_data(self.device.id) 73 if self.opencl_cache is not None: 74 batch.remove_data(self.opencl_cache.id) 75 if self.lvcs is not None: 76 batch.remove_data(self.lvcs.id) 77 78 # describe scene (returns data path) 79 def describe(self): 80 return self.description 81 82 def modify_appearance(self, app1, app2): 83 status = boxm2_adaptor.modify_scene_appearance(self.scene, app1, app2) 84 self.rgb = self.description['appType'] 85 return status 86 # returns scene bounding box 87 88 def bounding_box(self): 89 return self.bbox 90 91 def lvcs(self): 92 return self.lvcs 93 94 def cache(): 95 return self.cache 96 def _get_device_cache(self, device_string): 97 dev = self.device 98 99 if device_string: 100 # check if force gpu or cpu 101 if device_string[0:3] == "gpu" or device_string[0:3] == "cpu": 102 cache = self.opencl_cache 103 elif device_string == "cpp": 104 cache = self.cpu_cache 105 dev = None 106 else: 107 cache = self.active_cache 108 109 return (dev, cache) 110 111 def transform_to_scene(self, to_scene, trans, rot, scale): 112 if self.opencl_cache.type == "boxm2_opencl_cache_sptr": 113 print("transforming scene") 114 batch.init_process("boxm2VecfOclTransformSceneProcess") 115 batch.set_input_from_db(0, self.scene) 116 batch.set_input_from_db(1, to_scene) 117 batch.set_input_from_db(2, self.opencl_cache) 118 batch.set_input_double(3, trans[0]) 119 batch.set_input_double(4, trans[1]) 120 batch.set_input_double(5, trans[2]) 121 batch.set_input_double(6, rot[0][0]) 122 batch.set_input_double(7, rot[0][1]) 123 batch.set_input_double(8, rot[0][2]) 124 batch.set_input_double(9, rot[1][0]) 125 batch.set_input_double(10, rot[1][1]) 126 batch.set_input_double(11, rot[1][2]) 127 batch.set_input_double(12, rot[2][0]) 128 batch.set_input_double(13, rot[2][1]) 129 batch.set_input_double(14, rot[2][2]) 130 batch.set_input_double(15, scale[0]) 131 batch.set_input_double(16, scale[1]) 132 batch.set_input_double(17, scale[2]) 133 134 return batch.run_process() 135 else: 136 print "ERROR: Cache type not recognized: ", self.opencl_cache.type 137 return False 138 139 def init_alpha(self, pinit=0.01, thresh=1.0): 140 cache = self.opencl_cache 141 dev = self.device 142 boxm2_adaptor.init_alpha(self.scene, cache, dev, pinit, thresh) 143 144 # update with alternate explaination prior and appearance density 145 def update_with_alt(self, cam, img, update_alpha=True, 146 mask=None, var=-1.0, alt_prior=None, alt_density=None): 147 cache = self.opencl_cache 148 dev = self.device 149 boxm2_adaptor.update_grey_with_alt(self.scene, cache, cam, img, dev, 150 "", mask, update_alpha, var, alt_prior, alt_density) 151 # update wrapper, can pass in a Null device to use 152 153 def update(self, cam, img, update_alpha=True, update_app=True, mask=None, 154 device_string="", var=-1.0, ident_string="", tnear=100000.0, tfar=100000.0): 155 dev, cache = self._get_device_cache(device_string) 156 157 # run update grey or RGB 158 if self.rgb: 159 if self.view: 160 return boxm2_adaptor.update_rgb_view_dep(self.scene, cache, cam, img, dev, 161 ident_string, mask, update_alpha, var) 162 else: 163 return boxm2_adaptor.update_rgb(self.scene, cache, cam, 164 img, dev, "", update_alpha) 165 else: 166 if self.view: 167 return boxm2_adaptor.update_grey_view_dep(self.scene, cache, cam, img, dev, 168 ident_string, mask, update_alpha, var) 169 else: 170 return boxm2_adaptor.update_grey(self.scene, cache, cam, img, dev, ident_string, 171 mask, update_alpha, var, update_app, tnear, tfar) 172 173 # update wrapper, can pass in a Null device to use 174 def update_app(self, cam, img, device_string="", force_grey=False): 175 if device_string and device_string[0:3] == "cpp": 176 print " Not implemented in C++ yet " 177 return 178 179 dev, cache = self._get_device_cache(device_string) 180 181 if self.rgb and not force_grey: 182 boxm2_adaptor.update_rgb(self.scene, cache, cam, img, dev, "", False) 183 else: 184 boxm2_adaptor.update_app_grey(self.scene, cache, cam, img, dev) 185 186 # update skky wrapper, can pass in a Null device to use 187 def update_sky(self, cam, img, device_string=""): 188 if device_string and device_string[0:3] == "cpp": 189 print " Not implemented in C++ yet " 190 return 191 192 dev, cache = self._get_device_cache(device_string) 193 194 boxm2_adaptor.update_sky(self.scene, cache, cam, img, dev) 195 # update skky wrapper, can pass in a Null device to use 196 197 def update_sky2(self, cam, img, step, device_string=""): 198 if device_string and device_string[0:3] == "cpp": 199 print " Not implemented in C++ yet " 200 return 201 202 dev, cache = self._get_device_cache(device_string) 203 204 boxm2_adaptor.update_sky2(self.scene, cache, cam, img, step, dev) 205 206 # render wrapper, same as above 207 def render(self, cam, ni=1280, nj=720, device_string="", ident_string="", 208 tnear=1000000.0, tfar=1000000.0, ): 209 dev, cache = self._get_device_cache(device_string) 210 if self.rgb: 211 if self.view: 212 expimg = boxm2_adaptor.render_rgb_view_dep(self.scene, cache, cam, 213 ni, nj, dev, ident_string) 214 else: 215 expimg, vis_image, status = boxm2_adaptor.render_rgb( 216 self.scene, cache, cam, ni, nj, dev, tnear, tfar) 217 batch.remove_data(vis_image.id) 218 else: 219 if self.view: 220 expimg = boxm2_adaptor.render_grey_view_dep(self.scene, cache, cam, 221 ni, nj, dev, ident_string) 222 else: 223 expimg = boxm2_adaptor.render_grey(self.scene, cache, cam, 224 ni, nj, dev, ident_string, tnear, tfar) 225 return expimg 226 227 # render wrapper, same as above 228 def render_vis(self, cam, ni=1280, nj=720, device_string="", ident=""): 229 dev, cache = self._get_device_cache(device_string) 230 if self.rgb: 231 expimg, vis_image, status = boxm2_adaptor.render_rgb( 232 self.scene, cache, cam, ni, nj, dev) 233 else: 234 expimg, vis_image = boxm2_adaptor.render_grey_and_vis( 235 self.scene, cache, cam, ni, nj, dev, ident) 236 return expimg, vis_image 237 238 # render depth image wrapper 239 def render_depth(self, cam, ni=1280, nj=720, device_string=""): 240 dev, cache = self._get_device_cache(device_string) 241 expimg, varimg, visimg = boxm2_adaptor.render_depth( 242 self.scene, cache, cam, ni, nj, dev) 243 return expimg, varimg, visimg 244 245 # render the depth of the surfaces with max probability of being the the 246 # first visible and occupied surface along the rays 247 def render_depth_of_max_prob_surface( 248 self, cam, ni=1280, nj=720, device_string=""): 249 dev, cache = self._get_device_cache(device_string) 250 expimg, probimg, visimg = boxm2_adaptor.render_depth_of_max_prob_surface( 251 self.scene, cache, cam, ni, nj, dev) 252 return expimg, probimg, visimg 253 254 # render depth image with loading given region wrapper 255 def render_depth_region(self, cam, lat, lon, elev, 256 radius, ni=1280, nj=720, device_string=""): 257 dev, cache = self._get_device_cache(device_string) 258 expimg, varimg, visimg = boxm2_adaptor.render_depth_region( 259 self.scene, cache, cam, lat, lon, elev, radius, ni, nj, dev) 260 return expimg, varimg, visimg 261 262 # render z image wrapper 263 def render_z_image(self, cam, ni=1280, nj=720, 264 normalize=False, device_string=""): 265 dev, cache = self._get_device_cache(device_string) 266 z_exp_img, z_var_img = boxm2_adaptor.render_z_image( 267 self.scene, cache, cam, ni, nj, normalize, dev) 268 return z_exp_img, z_var_img 269 270 # render heigh map render 271 def render_height_map(self, device_string=""): 272 dev, cache = self._get_device_cache(device_string) 273 z_image, var_image, x_image, y_image, prob_image = \ 274 boxm2_adaptor.render_height_map(self.scene, cache, dev) 275 return z_image, var_image, x_image, y_image, prob_image 276 277 # ingest heigh map 278 def ingest_height_map(self, x_img, y_img, z_img, 279 zero_out_alpha=True, device_string=""): 280 dev, cache = self._get_device_cache(device_string) 281 boxm2_adaptor.ingest_height_map(self.scene, cache, x_img, y_img, 282 z_img, zero_out_alpha, dev) 283 return 284 285 # ingest heigh map 286 def ingest_height_map_space( 287 self, x_img, y_img, z_img, crust_thickness, device_string=""): 288 dev, cache = self._get_device_cache(device_string) 289 boxm2_adaptor.ingest_height_map_space(self.scene, cache, x_img, 290 y_img, z_img, crust_thickness, dev) 291 return 292 293 # ingest to zero out alphas along the rays given by the input images 294 def ingest_to_zero_out_alpha(self, x_img, y_img, z_img, device_string=""): 295 dev, cache = self._get_device_cache(device_string) 296 boxm2_adaptor.ingest_to_zero_out_alpha(self.scene, cache, x_img, y_img, 297 z_img, dev) 298 return 299 300 # ingest label map 301 # def ingest_label_map(self,x_img,y_img,z_img,label_img,device_string="") : 302 def ingest_label_map(self, x_img, y_img, z_img, 303 label_img, ident, device_string=""): 304 dev, cache = self._get_device_cache(device_string) 305 # ingest_label_map(self.scene, cache, x_img, y_img, z_img, label_img, dev); 306 boxm2_adaptor.ingest_label_map(self.scene, cache, x_img, y_img, 307 z_img, label_img, ident, dev) 308 return 309 310 # ingest label map 311 def ingest_osm_label_map(self, x_img, y_img, z_img, 312 label_img, ident="land", device_string=""): 313 dev, cache = self._get_device_cache(device_string) 314 boxm2_adaptor.ingest_osm_label_map(self.scene, cache, x_img, 315 y_img, z_img, label_img, ident, dev) 316 return 317 318 # ingest buckeye-style dem 319 def ingest_buckeye_dem(self, first_ret_fname, last_ret_fname, 320 geoid_height, geocam, device_string=""): 321 dev, cache = self._get_device_cache(device_string) 322 boxm2_adaptor.ingest_buckeye_dem(self.scene, cache, first_ret_fname, 323 last_ret_fname, geoid_height, geocam, 324 dev) 325 return 326 327 def probability_of(self, cam, image): 328 cache = self.active_cache 329 dev = self.device 330 outimg = boxm2_adaptor.compute_probability_of_image( 331 self.device, self.scene, self.opencl_cache, cam, image) 332 return outimg 333 334 def cubic_probability_of(self, cam, image, model_ident, img_ident): 335 cache = self.active_cache 336 dev = self.device 337 outimg = boxm2_adaptor.cubic_compute_probability_of_image( 338 self.device, self.scene, self.opencl_cache, cam, image, model_ident, img_ident) 339 return outimg 340 341 # detect change wrapper, 342 def change_detect(self, cam, img, exp_img, n=1, raybelief="", 343 max_mode=False, rgb=False, device_string="", ident=""): 344 dev, cache = self._get_device_cache(device_string) 345 cd_img = boxm2_adaptor.change_detect(self.scene, cache, cam, img, 346 exp_img, dev, rgb, n, raybelief, max_mode, ident) 347 return cd_img 348 349 # detect change wrapper, 350 def change_detect2(self, cam, img, identifier="", max_mode=False, 351 tnear=10000000, tfar=0.00001, device_string=""): 352 dev, cache = self._get_device_cache(device_string) 353 cd_img, vis_img = boxm2_adaptor.change_detect2( 354 self.scene, cache, cam, img, identifier, max_mode, tnear, tfar, dev) 355 return cd_img, vis_img 356 357 def refine(self, thresh=0.3, device_string=""): 358 dev, cache = self._get_device_cache(device_string) 359 return boxm2_adaptor.refine(self.scene, cache, thresh, dev) 360 361 def merge(self, thresh=0.3, device_string=""): 362 dev, cache = self._get_device_cache(device_string) 363 boxm2_adaptor.merge(self.scene, cache, thresh, dev) 364 365 def median_filter(self, device_string=""): 366 dev, cache = self._get_device_cache(device_string) 367 boxm2_adaptor.median_filter(self.scene, cache, dev) 368 369 # given the scene, chip the NITF and setup the camera 370 def roi_init(self, NITF_path, camera, convert_to_8bit, 371 params_fname, margin=0, clip_width=-1, clip_height=-1): 372 return boxm2_adaptor.roi_init(NITF_path, camera, self.scene, convert_to_8bit, 373 params_fname, margin, clip_width, clip_height) 374 375 # Apply multiple filters to scene 376 def kernel_vector_filter(self, filters): 377 return boxm2_filtering_adapto.apply_filters(self.scene, self.opencl_cache, 378 self.device, filters) 379 380 # Interpolate normal from various responses 381 def interpolate_normals(self, filters): 382 return boxm2_filtering_adaptor.interpolate_normals(self.scene, 383 self.opencl_cache, self.device, filters) 384 385 # Extract cell centers to XYZ for fast access 386 def extract_cell_centers(self, prob_thresh=0.0): 387 return boxm2_tools_adaptor.extract_cell_centers(self.scene, 388 self.cpu_cache, prob_thresh=0.0) 389 390 # Flip normals towards direction of maximum visibility 391 def flip_normals(self, use_sum=False): 392 return boxm2_filtering_adaptor.flip_normals(self.scene, 393 self.opencl_cache, self.device, use_sum) 394 395 # Export points and normals to a .PLY file or XYZ. Points and normals need 396 # to be extracted first 397 def export_points_and_normals(self, file_out, save_aux=True, 398 prob_thresh=0.0, vis_thresh=0.0, 399 nmag_thresh=0.0, exp_thresh=0.0, 400 bbox_file=""): 401 return boxm2_tools_adaptor.export_points_and_normals(self.scene, 402 self.cpu_cache, file_out, save_aux, prob_thresh, vis_thresh, 403 nmag_thresh, exp_thresh, bbox_file) 404 405 # Adds auxiliary data to vertices in a .PLY 406 def add_aux_info_to_ply(self, file_in, file_out): 407 boxm2_tools_adaptor.add_aux_info_to_ply(self.scene, self.cpu_cache, 408 file_in, file_out) 409 410 # only write the cpu_cache to disk 411 def write_cache(self, do_clear=0): 412 boxm2_adaptor.write_cache(self.cpu_cache, do_clear) 413 414 # clear cache (both caches if OPENCL scene) 415 def clear_cache(self): 416 boxm2_adaptor.clear_cache(self.cpu_cache) 417 if self.opencl_cache: 418 boxm2_adaptor.clear_cache(self.opencl_cache) 419 420 ################################ 421 # get info functions 422 def get_info_along_ray(self, cam, u, v, prefix, identifier=""): 423 return boxm2_tools_adaptor.get_info_along_ray(self.scene, 424 self.cpu_cache, cam, u, v, prefix, identifier) 425 426 def query_cell_brdf(self, point, model_type): 427 return boxm2_tools_adaptor.query_cell_brdf(self.scene, self.cpu_cache, 428 point, model_type) 429 430 ##################################################################### 431 ######### BATCH UPDATE METHODS ###################################### 432 ##################################################################### 433 def create_stream_cache(self, imgs, interval=1, types="", max_gb=6.0): 434 435 # write image identifiers to file 436 # imgRange = range(0, len(imgs), interval); 437 # num_imgs = len(imgRange); 438 image_id_fname = self.model_dir + "/image_list.txt" 439 fd = open(image_id_fname, "w") 440 print >> fd, len(imgs) 441 # for i in imgRange: 442 # print >>fd, "img_%05d"%i 443 for img in imgs: 444 fname, fextension = os.path.splitext(img) 445 bname = os.path.basename(fname) 446 print >> fd, bname 447 fd.close() 448 449 # write type identifiers into file 450 type_id_fname = self.model_dir + "/type_names_list.txt" 451 fd2 = open(type_id_fname, "w") 452 print >>fd2, 4 453 print >>fd2, "aux0" 454 print >>fd2, "aux1" 455 print >>fd2, "aux2" 456 print >>fd2, "aux3" 457 fd2.close() 458 459 # open the stream cache, this is a read-only cache 460 batch.init_process("boxm2CreateStreamCacheProcess") 461 batch.set_input_from_db(0, self.scene) 462 batch.set_input_string(1, type_id_fname) 463 batch.set_input_string(2, image_id_fname) 464 batch.set_input_float(3, max_gb) 465 batch.run_process() 466 (cache_id, cache_type) = batch.commit_output(0) 467 self.str_cache = dbvalue(cache_id, cache_type) 468 469 # remove stream cache object from database 470 def destroy_stream_cache(self): 471 if self.str_cache: 472 batch.remove_data(self.str_cache.id) 473 self.str_cache = None 474 475 # writes aux data for each image in imgs array 476 def write_aux_data(self, imgs, cams): 477 for idx in range(len(imgs)): 478 print '--------------------------' 479 print "processing image " + imgs[idx] 480 481 # load cam/img 482 img, ni, nj = vil_adaptor.load_image(imgs[idx]) 483 pcam = vpgl_adaptor.load_perspective_camera(cams[idx]) 484 gcam = vpgl_adaptor.persp2gen(pcam, ni, nj) 485 486 # update aux per view call 487 fname, fextension = os.path.splitext(imgs[idx]) 488 imageID = os.path.basename(fname) 489 self.update_aux(img, gcam, imageID) 490 491 # create an imagewise aux buffer for cam/img 492 def update_aux(self, img, cam, imgId, device_string="", mask=None): 493 dev, cache = self._get_device_cache(device_string) 494 boxm2_adaptor.update_aux_per_view(self.scene, cache, img, cam, imgId, 495 dev, mask) 496 497 # create an imagewise aux buffer for batch update of normal-albedo-array 498 # appearance model 499 def update_aux_naa(self, img, cam, metadata, atm_params, imgId, alt_prior, 500 alt_density): 501 boxm2_adaptor.update_aux_per_view_naa(self.scene, self.opencl_cache, 502 img, cam, metadata, atm_params, imgId, alt_prior, alt_density, 503 self.device) 504 505 # takes already created aux buffers (for each image) and fits a Mixture of 3 506 # Gaussians to each cell, saves the appearance 507 def batch_paint(self, imgs, cams, device_string=""): 508 # verify stream cache 509 if (self.str_cache is None): 510 self.create_stream_cache(imgs) 511 512 # sigma norm table? 513 under_estimation_probability = 0.2 514 batch.init_process("bstaSigmaNormTableProcess") 515 batch.set_input_float(0, under_estimation_probability) 516 batch.run_process() 517 (id, type) = batch.commit_output(0) 518 n_table = dbvalue(id, type) 519 520 # call batch paint process 521 if device_string == "": 522 batch.init_process("boxm2OclPaintBatchProcess") 523 batch.set_input_from_db(0, self.device) 524 batch.set_input_from_db(1, self.scene) 525 batch.set_input_from_db(2, self.opencl_cache) 526 batch.set_input_from_db(3, self.str_cache) 527 batch.set_input_from_db(4, n_table) 528 batch.run_process() 529 elif device_string == "cpu": 530 batch.init_process("boxm2CppBatchUpdateAppProcess") 531 batch.set_input_from_db(0, self.scene) 532 batch.set_input_from_db(1, self.cpu_cache) 533 batch.set_input_from_db(2, self.str_cache) 534 batch.set_input_from_db(3, n_table) 535 batch.run_process() 536 537 # close the files so that they can be reloaded after the next iteration 538 batch.init_process("boxm2StreamCacheCloseFilesProcess") 539 batch.set_input_from_db(0, self.str_cache) 540 batch.run_process() 541 542 # write out afterwards 543 self.write_cache() 544 545 def cpu_batch_paint(self, imgs, cams): 546 if (self.str_cache is None): 547 self.create_stream_cache(imgs) 548 549 # sigma norm table? 550 under_estimation_probability = 0.2 551 batch.init_process("bstaSigmaNormTableProcess") 552 batch.set_input_float(0, under_estimation_probability) 553 batch.run_process() 554 (id, type) = batch.commit_output(0) 555 n_table = dbvalue(id, type) 556 557 # loop over images creating aux data 558 for idx in range(0, len(imgs)): 559 560 # load cam/img 561 img, ni, nj = vil_adaptor.load_image(imgs[idx]) 562 pcam = vpgl_adaptor.load_perspective_camera(cams[idx]) 563 gcam = vpgl_adaptor.persp2gen(pcam, ni, nj) 564 565 # create norm intensity (num rays...) 566 batch.init_process("boxm2CppCreateNormIntensitiesProcess") 567 batch.set_input_from_db(0, self.scene) 568 batch.set_input_from_db(1, self.cpu_cache) 569 batch.set_input_from_db(2, gcam) 570 batch.set_input_from_db(3, img) 571 batch.set_input_string(4, "img_" + "%05d" % idx) 572 batch.run_process() 573 574 # create aux 575 batch.init_process("boxm2CppCreateAuxDataOPT2Process") 576 batch.set_input_from_db(0, self.scene) 577 batch.set_input_from_db(1, self.cpu_cache) 578 batch.set_input_from_db(2, gcam) 579 batch.set_input_from_db(3, img) 580 batch.set_input_string(4, "img_" + "%05d" % idx) 581 batch.run_process() 582 self.write_cache(True) 583 584 batch.init_process("boxm2CppBatchUpdateOPT2Process") 585 batch.set_input_from_db(0, self.scene) 586 batch.set_input_from_db(1, self.cpu_cache) 587 batch.set_input_from_db(2, self.str_cache) 588 batch.set_input_from_db(3, n_table) 589 batch.run_process() 590 591 # close the files so that they can be reloaded after the next iteration 592 batch.init_process("boxm2StreamCacheCloseFilesProcess") 593 batch.set_input_from_db(0, self.str_cache) 594 batch.run_process() 595 596 self.write_cache() 597 598 def cpu_batch_compute_normal_albedo( 599 self, metadata_filename_list, atmospheric_params_filename_list): 600 batch.init_process("boxm2CppBatchComputeNormalAlbedoProcess") 601 batch.set_input_from_db(0, self.scene) 602 batch.set_input_from_db(1, self.cpu_cache) 603 batch.set_input_from_db(2, self.str_cache) 604 batch.set_input_string(3, metadata_filename_list) 605 batch.set_input_string(4, atmospheric_params_filename_list) 606 batch.run_process() 607 608 # close the files so that they can be reloaded after the next iteration 609 batch.init_process("boxm2StreamCacheCloseFilesProcess") 610 batch.set_input_from_db(0, self.str_cache) 611 batch.run_process() 612 613 def ocl_batch_compute_normal_albedo( 614 self, img_id_list, metadata_filename_list, atmospheric_params_filename_list): 615 batch.init_process( 616 "boxm2OclBatchComputeNormalAlbedoArrayProcess") 617 batch.set_input_from_db(0, self.device) 618 batch.set_input_from_db(1, self.scene) 619 batch.set_input_from_db(2, self.opencl_cache) 620 batch.set_input_string(3, img_id_list) 621 batch.set_input_string(4, metadata_filename_list) 622 batch.set_input_string(5, atmospheric_params_filename_list) 623 batch.run_process() 624 625 def render_expected_image_naa( 626 self, camera, ni, nj, metadata, atmospheric_params): 627 batch.init_process("boxm2OclRenderExpectedImageNAAProcess") 628 batch.set_input_from_db(0, self.device) 629 batch.set_input_from_db(1, self.scene) 630 batch.set_input_from_db(2, self.opencl_cache) 631 batch.set_input_from_db(3, camera) 632 batch.set_input_unsigned(4, ni) 633 batch.set_input_unsigned(5, nj) 634 batch.set_input_from_db(6, metadata) 635 batch.set_input_from_db(7, atmospheric_params) 636 batch.run_process() 637 (id, type) = batch.commit_output(0) 638 exp_image = dbvalue(id, type) 639 (id, type) = batch.commit_output(1) 640 mask_image = dbvalue(id, type) 641 return(exp_image, mask_image) 642 643 def update_alpha_naa(self, image, camera, metadata, 644 atmospheric_params, alt_prior, alt_density): 645 batch.init_process("boxm2OclUpdateAlphaNAAProcess") 646 batch.set_input_from_db(0, self.device) 647 batch.set_input_from_db(1, self.scene) 648 batch.set_input_from_db(2, self.opencl_cache) 649 batch.set_input_from_db(3, camera) 650 batch.set_input_from_db(4, image) 651 batch.set_input_from_db(5, metadata) 652 batch.set_input_from_db(6, atmospheric_params) 653 batch.set_input_from_db(7, alt_prior) 654 batch.set_input_from_db(8, alt_density) 655 if not (batch.run_process()): 656 print("ERROR: run_process() returned False") 657 return 658 659 def render_expected_albedo_normal(self, camera, ni, nj): 660 batch.init_process("boxm2OclRenderExpectedAlbedoNormalProcess") 661 batch.set_input_from_db(0, self.device) 662 batch.set_input_from_db(1, self.scene) 663 batch.set_input_from_db(2, self.opencl_cache) 664 batch.set_input_from_db(3, camera) 665 batch.set_input_unsigned(4, ni) 666 batch.set_input_unsigned(5, nj) 667 batch.run_process() 668 (id, type) = batch.commit_output(0) 669 exp_albedo = dbvalue(id, type) 670 (id, type) = batch.commit_output(1) 671 exp_normal = dbvalue(id, type) 672 (id, type) = batch.commit_output(2) 673 mask_image = dbvalue(id, type) 674 return(exp_albedo, exp_normal, mask_image) 675 676 def transform(self, tx, ty, tz, rx, ry, rz, scale): 677 batch.init_process("boxm2TransformModelProcess") 678 batch.set_input_from_db(0, self.scene) 679 batch.set_input_float(1, tx) 680 batch.set_input_float(2, ty) 681 batch.set_input_float(3, tz) 682 batch.set_input_float(4, rx) 683 batch.set_input_float(5, ry) 684 batch.set_input_float(6, rz) 685 batch.set_input_float(7, scale) 686 batch.run_process() 687 return 688 689 def compute_sun_affine_camera(self, sun_az, sun_el, astro_coords=True): 690 (camera, ni, nj) = boxm2_adaptor.compute_sun_affine_camera( 691 self.scene, sun_az, sun_el, astro_coords) 692 return (camera, ni, nj) 693 694 def update_sun_visibilities(self, sun_camera, ni, nj, prefix_name=""): 695 boxm2_adaptor.update_sun_visibilities(self.scene, self.device, 696 self.opencl_cache, self.cpu_cache, sun_camera, ni, nj, prefix_name) 697 698 def render_shadow_map(self, camera, ni, nj, prefix_name=''): 699 shadow_map = boxm2_adaptor.render_shadow_map( 700 self.scene, self.device, self.opencl_cache, camera, ni, nj, 701 prefix_name) 702 return shadow_map 703 704 def render_scene_mask(self, camera, ni, nj, ground_plane_only=False): 705 mask = boxm2_adaptor.create_mask_image(self.scene, camera, ni, nj, 706 ground_plane_only) 707 return mask 708 709 def normals_to_id(self): 710 print("Normals to id ") 711 batch.init_process("boxm2CppNormalsToIdProcess") 712 batch.set_input_from_db(0, self.scene) 713 batch.set_input_from_db(1, self.cpu_cache) 714 return batch.run_process() 715 716 def cache_neighbor_info(self): 717 batch.init_process("boxm2VecfOclCacheNeighborInfoProcess") 718 batch.set_input_from_db(0, self.scene) 719 batch.set_input_from_db(1, self.opencl_cache) 720 return batch.run_process() 721 722 def refine_scene_around_geometry( 723 self, filter_v, n_times, p_thresh, use_gpu): 724 if self.opencl_cache.type == "boxm2_opencl_cache_sptr": 725 print("Refining around surface geometry") 726 batch.init_process( 727 "boxm2_ocl_refine_scene_around_geometry_process") 728 batch.set_input_from_db(0, self.scene) 729 batch.set_input_from_db(1, self.opencl_cache) 730 batch.set_input_from_db(2, self.device) 731 batch.set_input_from_db(3, filter_v) 732 batch.set_input_int(4, n_times) 733 # use negative value to refine all 734 batch.set_input_float(5, p_thresh) 735 batch.set_input_bool(6, use_gpu) 736 return batch.run_process() 737 else: 738 print "ERROR: Cache type not recognized: ", self.opencl_cache.type 739 return False 740 741 def compute_pre_post(self, cam, img, view_identifier="", 742 tnear=100000.0, tfar=100000.0): 743 dev = self.device 744 cache = self.opencl_cache 745 return boxm2_adaptor.boxm2_compute_pre_post( 746 self.scene, dev, cache, cam, img, view_identifier, tnear, tfar) 747 748 def update_if(self, does_add=True, view_identifier=""): 749 dev = self.device 750 cache = self.opencl_cache 751 return boxm2_adaptor.update_image_factor( 752 self.scene, dev, cache, does_add, view_identifier) 753 754 def fuse_factors(self, view_idents, weights): 755 dev = self.device 756 cache = self.opencl_cache 757 return boxm2_adaptor.boxm2_fuse_factors(self.scene, dev, cache, view_idents, weights) 758 759 def compute_hmapf(self, zimg, zvar, ximg, yimg, sradius=16): 760 dev = self.device 761 cache = self.opencl_cache 762 return boxm2_adaptor.compute_hmap_factor( 763 self.scene, dev, cache, zimg, zvar, ximg, yimg, sradius) 764 765 def update_hf(self, does_add=True): 766 dev = self.device 767 cache = self.opencl_cache 768 return boxm2_adaptor.update_hmap_factor(self.scene, dev, cache, does_add) 769 770 def init_uniform_prob(self): 771 return boxm2_adaptor.boxm2_init_uniform_prob( 772 self.scene, self.device, self.opencl_cache) 773 774 def remove_low_nobs(self, nobs_thresh_multiplier=3.0): 775 dev = self.device 776 cache = self.opencl_cache 777 return boxm2_adaptor.boxm2_remove_low_nobs( 778 self.scene, dev, cache, nobs_thresh_multiplier) 779 780 781def compactify_mog6_view_scene(boxm2_dir, save_dir=None): 782 if save_dir is None: 783 save_dir = os.path.join(boxm2_dir, "sav") 784 original_scene_file = os.path.join(boxm2_dir, 'scene.xml') 785 compact_scene_file = os.path.join(boxm2_dir, 'compact_scene.xml') 786 787 # load scene 788 scene = boxm2_scene_adaptor(original_scene_file) 789 boxm2_adaptor.compactify_mog6_view(scene.scene, scene.cpu_cache) 790 scene.write_cache() 791 792 # create new compact scene file with updated appearance model 793 tree = ElementTree() 794 tree.parse(original_scene_file) 795 root = tree.getroot() 796 for apm in root.iter('appearance'): 797 if "mog6" in apm.get('apm'): 798 apm.set('apm', 'boxm2_mog6_view_compact') 799 else: 800 root.remove(apm) 801 tree.write(compact_scene_file) 802 803 # remove un-compactified data files 804 old_data_files_pattern = r"boxm2_(mog6_view_id|num_obs|vis)" 805 for f in os.listdir(boxm2_dir): 806 if re.search(old_data_files_pattern, f): 807 os.remove(os.path.join(boxm2_dir, f)) 808 809 # copy files to save directory 810 if not os.path.isdir(save_dir): 811 os.mkdir(save_dir) 812 else: 813 for f in os.listdir(save_dir): 814 if re.search(r".*\.bin", f): 815 os.remove(os.path.join(save_dir, f)) 816 817 id_pat = [r'^id_', r'^boxm2_mog6_view_compact_id', r'^alpha_id_'] 818 for pat in id_pat: 819 save_pattern(boxm2_dir, pat, save_dir) 820 shutil.copy(os.path.join(boxm2_dir, 'compact_scene.xml'), save_dir) 821 rewriteScenePath(save_dir, 'compact_scene.xml') 822 823 824def save_pattern(search_dir, pattern, save_dir): 825 """Copies all files in `search_dir` that match the given `pattern` 826 into `save_dir`. If `save_dir` does not exist then nothing is 827 done. 828 829 :param search_dir: Directory from which to copy files 830 :param pattern: Regex string to match files in `search_dir` 831 :param save_dir: Absolute path in which to save copied files from 832 `search_dir` 833 """ 834 if not os.path.exists(save_dir): 835 return 836 837 for f in os.listdir(search_dir): 838 if re.search(pattern, f): 839 shutil.copy(os.path.join(search_dir, f), save_dir) 840 841 842def rewriteScenePath(boxm2_dir, scene_file): 843 """Rewrites a given scene XML file with a new scene_paths element 844 that points to its containing directory. 845 846 :param boxm2_dir: The directory containing the given scene file. 847 :param scene_file: Relative path from `boxm2_dir` to the given 848 XML file to modify. 849 850 """ 851 abs_name = os.path.join(boxm2_dir, scene_file) 852 if os.path.isfile(abs_name): 853 tree = ElementTree() 854 tree.parse(abs_name) 855 root = tree.getroot() 856 for path in root.iter('scene_paths'): 857 path.set('path', boxm2_dir + '/') 858 tree.write(abs_name) 859