1# import the batch module and dbvalue from init 2# set the global variable, batch, on init before importing this file 3 4import brl_init 5dbvalue = brl_init.DummyBatch() 6batch = brl_init.DummyBatch() 7 8 9class VpglException(brl_init.BrlException): 10 pass 11 12############################################################################# 13# PROVIDES higher level vpgl python functions to make batch 14# code more readable/refactored 15############################################################################# 16 17import math 18 19# ; 20# camera loading; 21# ; 22 23 24def load_perspective_camera(file_path): 25 batch.init_process("vpglLoadPerspectiveCameraProcess") 26 batch.set_input_string(0, file_path) 27 batch.run_process() 28 (id, type) = batch.commit_output(0) 29 cam = dbvalue(id, type) 30 return cam 31 32 33def load_affine_camera(file_path, viewing_dist=1000, look_dir=(0, 0, -1)): 34 """ load an affine camera from a text file containing the projection matrix 35 The viewing rays will be flipped such that the dot product with look_dir is positive 36 """ 37 batch.init_process("vpglLoadAffineCameraProcess") 38 batch.set_input_string(0, file_path) 39 batch.set_input_double(1, viewing_dist) 40 batch.set_input_double(2, look_dir[0]) 41 batch.set_input_double(3, look_dir[1]) 42 batch.set_input_double(4, look_dir[2]) 43 batch.run_process() 44 (id, type) = batch.commit_output(0) 45 cam = dbvalue(id, type) 46 return cam 47 48 49def load_projective_camera(file_path): 50 batch.init_process("vpglLoadProjCameraProcess") 51 batch.set_input_string(0, file_path) 52 batch.run_process() 53 (id, type) = batch.commit_output(0) 54 cam = dbvalue(id, type) 55 return cam 56 57#Scale = (scale_u, scale_v), ppoint = (u,v), center = (x,y,z), look_pt = (x,y,z), up = (x,y,z); 58def create_perspective_camera(scale, ppoint, center, look_pt, up=[0, 1, 0]): 59 batch.init_process("vpglCreatePerspectiveCameraProcess") 60 batch.set_input_double(0, scale[0]) 61 batch.set_input_double(1, ppoint[0]) 62 batch.set_input_double(2, scale[1]) 63 batch.set_input_double(3, ppoint[1]) 64 batch.set_input_double(4, center[0]) 65 batch.set_input_double(5, center[1]) 66 batch.set_input_double(6, center[2]) 67 batch.set_input_double(7, look_pt[0]) 68 batch.set_input_double(8, look_pt[1]) 69 batch.set_input_double(9, look_pt[2]) 70 batch.run_process() 71 (id, type) = batch.commit_output(0) 72 cam = dbvalue(id, type) 73 return cam 74 75 76def create_perspective_camera_from_kml(ni, nj, right_fov, top_fov, altitude, heading, tilt, roll, cent_x, cent_y): 77 batch.init_process("vpglCreatePerspCameraFromKMLProcess") 78 batch.set_input_unsigned(0, ni) 79 batch.set_input_unsigned(1, nj) 80 batch.set_input_double(2, right_fov) 81 batch.set_input_double(3, top_fov) 82 batch.set_input_double(4, altitude) 83 batch.set_input_double(5, heading) 84 batch.set_input_double(6, tilt) 85 batch.set_input_double(7, roll) 86 batch.set_input_double(8, cent_x) 87 batch.set_input_double(9, cent_y) 88 batch.run_process() 89 (id, type) = batch.commit_output(0) 90 cam = dbvalue(id, type) 91 return cam 92 93 94def load_perspective_camera_from_kml_file(NI, NJ, kml_file): 95 batch.init_process("vpglLoadPerspCameraFromKMLFileProcess") 96 batch.set_input_unsigned(0, NI) 97 batch.set_input_unsigned(1, NJ) 98 batch.set_input_string(2, kml_file) 99 batch.run_process() 100 (id, type) = batch.commit_output(0) 101 cam = dbvalue(id, type) 102 (id, type) = batch.commit_output(1) 103 longitude = batch.get_output_double(id) 104 batch.remove_data(id) 105 (id, type) = batch.commit_output(2) 106 latitude = batch.get_output_double(id) 107 batch.remove_data(id) 108 (id, type) = batch.commit_output(3) 109 altitude = batch.get_output_double(id) 110 batch.remove_data(id) 111 return cam, longitude, latitude, altitude 112 113# resize a camera from size0 =(ni,nj) to size1 (ni_1, nj_1); 114def resample_perspective_camera(cam, size0, size1): 115 batch.init_process("vpglResamplePerspectiveCameraProcess") 116 batch.set_input_from_db(0, cam) 117 batch.set_input_int(1, size0[0]) 118 batch.set_input_int(2, size0[1]) 119 batch.set_input_int(3, size1[0]) 120 batch.set_input_int(4, size1[1]) 121 batch.run_process() 122 (id, type) = batch.commit_output(0) 123 out = dbvalue(id, type) 124 return out 125# resize a camera from size0 =(ni,nj) to size1 (ni_1, nj_1); 126def get_perspective_camera_center(cam): 127 batch.init_process("vpglGetPerspectiveCamCenterProcess") 128 batch.set_input_from_db(0, cam) 129 batch.run_process() 130 (id, type) = batch.commit_output(0) 131 x = batch.get_output_float(id) 132 batch.remove_data(id) 133 (id, type) = batch.commit_output(1) 134 y = batch.get_output_float(id) 135 batch.remove_data(id) 136 (id, type) = batch.commit_output(2) 137 z = batch.get_output_float(id) 138 batch.remove_data(id) 139 return x, y, z 140 141 142def get_backprojected_ray(cam, u, v): 143 batch.init_process("vpglGetBackprojectRayProcess") 144 batch.set_input_from_db(0, cam) 145 batch.set_input_float(1, u) 146 batch.set_input_float(2, v) 147 batch.run_process() 148 (id, type) = batch.commit_output(0) 149 x = batch.get_output_float(id) 150 batch.remove_data(id) 151 (id, type) = batch.commit_output(1) 152 y = batch.get_output_float(id) 153 batch.remove_data(id) 154 (id, type) = batch.commit_output(2) 155 z = batch.get_output_float(id) 156 batch.remove_data(id) 157 return x, y, z 158 159# returns cartesian cam center from azimuth (degrees), elevation 160# (degrees), radius, look point; 161def get_rpc_backprojected_ray(cam, u, v, altitude, initial_lon, initial_lat, initial_alt): 162 batch.init_process("vpglGetRpcBackprojectRayProcess") 163 batch.set_input_from_db(0, cam) 164 batch.set_input_double(1, u) 165 batch.set_input_double(2, v) 166 batch.set_input_double(3, altitude) 167 batch.set_input_double(4, initial_lon) 168 batch.set_input_double(5, initial_lat) 169 batch.set_input_double(6, initial_alt) 170 batch.run_process() 171 (id, type) = batch.commit_output(0) 172 x = batch.get_output_double(id) 173 batch.remove_data(id) 174 (id, type) = batch.commit_output(1) 175 y = batch.get_output_double(id) 176 batch.remove_data(id) 177 (id, type) = batch.commit_output(2) 178 z = batch.get_output_double(id) 179 batch.remove_data(id) 180 return x, y, z 181 182 183def get_camera_center(azimuth, elevation, radius, lookPt): 184 deg_to_rad = math.pi / 180.0 185 el = elevation * deg_to_rad 186 az = azimuth * deg_to_rad 187 cx = radius * math.sin(el) * math.cos(az) 188 cy = radius * math.sin(el) * math.sin(az) 189 cz = radius * math.cos(el) 190 center = (cx + lookPt[0], cy + lookPt[1], cz + lookPt[2]) 191 return center 192 193# returns spherical coordinates about sCenter given cartesian point; 194def cart2sphere(cartPt, sCenter): 195 # offset cart point; 196 cartPt = numpy.subtract(cartPt, sCenter) 197 rad = math.sqrt(sum(cartPt * cartPt)) 198 az = math.atan2(cartPt[1], cartPt[0]) 199 el = math.acos(cartPt[2] / rad) 200 return (math.degrees(az), math.degrees(el), rad) 201 202 203def load_rational_camera(file_path): 204 batch.init_process("vpglLoadRationalCameraProcess") 205 batch.set_input_string(0, file_path) 206 status = batch.run_process() 207 cam = None 208 if status: 209 (id, type) = batch.commit_output(0) 210 cam = dbvalue(id, type) 211 return cam 212 else: 213 raise VpglException("Failed to load Rational Camera") 214 215 216def load_local_rational_camera(file_path): 217 batch.init_process("vpglLoadLocalRationalCameraProcess") 218 batch.set_input_string(0, file_path) 219 batch.run_process() 220 (id, type) = batch.commit_output(0) 221 cam = dbvalue(id, type) 222 return cam 223 224 225def load_rational_camera_nitf(file_path): 226 batch.init_process("vpglLoadRationalCameraNITFProcess") 227 batch.set_input_string(0, file_path) 228 batch.run_process() 229 (id, type) = batch.commit_output(0) 230 cam = dbvalue(id, type) 231 return cam 232 233 234def load_rational_camera_from_txt(file_path): 235 batch.init_process("vpglLoadRationalCameraFromTXTProcess") 236 batch.set_input_string(0, file_path) 237 status = batch.run_process() 238 if status: 239 (id, type) = batch.commit_output(0) 240 cam = dbvalue(id, type) 241 return cam 242 else: 243 raise VpglException("Failed to load Rational Camera from txt") 244 245 246def convert_local_rational_perspective_camera(local_cam): 247 batch.init_process("vpglConvertLocalRationalToPerspectiveProcess") 248 batch.set_input_from_db(0, local_cam) 249 batch.run_process() 250 (id, type) = batch.commit_output(0) 251 cam = dbvalue(id, type) 252 return cam 253 254 255def create_local_rational_camera(rational_cam_fname, lvcs_fname): 256 batch.init_process('vpglCreateLocalRationalCameraProcess') 257 batch.set_input_string(0, rational_cam_fname) 258 batch.set_input_string(1, lvcs_fname) 259 batch.run_process() 260 (id, type) = batch.commit_output(0) 261 cam = dbvalue(id, type) 262 return cam 263 264 265def convert_to_local_rational_camera(rational_cam, lvcs): 266 batch.init_process('vpglConvertToLocalRationalCameraProcess') 267 batch.set_input_from_db(0, rational_cam) 268 batch.set_input_from_db(1, lvcs) 269 status = batch.run_process() 270 cam = None 271 if status: 272 (id, type) = batch.commit_output(0) 273 cam = dbvalue(id, type) 274 return cam 275 else: 276 raise VpglException("Failed to convert local rational camera") 277 278# ; 279# camera saving; 280# ; 281def print_rational_camera(camera): 282 batch.init_process("vpglPrintRationalCameraProcess") 283 batch.set_input_from_db(0, camera) 284 status = batch.run_process() 285 if status: 286 return 287 else: 288 raise VpglException("Failed to print rational camera") 289 290def save_rational_camera(camera, path): 291 batch.init_process("vpglSaveRationalCameraProcess") 292 batch.set_input_from_db(0, camera) 293 batch.set_input_string(1, path) 294 batch.run_process() 295 296 297def save_perspective_camera(camera, path): 298 batch.init_process("vpglSavePerspectiveCameraProcess") 299 batch.set_input_from_db(0, camera) 300 batch.set_input_string(1, path) 301 batch.run_process() 302 303 304def save_perspective_camera_vrml(camera, path): 305 batch.init_process("vpglSavePerspectiveCameraVrmlProcess") 306 batch.set_input_from_db(0, camera) 307 batch.set_input_string(1, path) 308 batch.set_input_float(2, 5.0) 309 batch.run_process() 310 311 312def save_perspective_cameras_vrml(camerafolder, path): 313 batch.init_process("vpglSavePerspectiveCamerasVrmlProcess") 314 batch.set_input_string(0, camerafolder) 315 batch.set_input_string(1, path) 316 batch.set_input_float(2, 5.0) 317 batch.run_process() 318 319 320def save_proj_camera(camera, path): 321 batch.init_process("vpglSaveProjectiveCameraProcess") 322 batch.set_input_from_db(0, camera) 323 batch.set_input_string(1, path) 324 batch.run_process() 325 326# ; 327# perspective go generic conversion; 328# ; 329def persp2gen(pcam, ni, nj, level=0): 330 batch.init_process("vpglConvertToGenericCameraProcess") 331 batch.set_input_from_db(0, pcam) 332 batch.set_input_unsigned(1, ni) 333 batch.set_input_unsigned(2, nj) 334 batch.set_input_unsigned(3, level) 335 status = batch.run_process() 336 gcam = None 337 if status: 338 (id, type) = batch.commit_output(0) 339 gcam = dbvalue(id, type) 340 return gcam 341 else: 342 raise VpglException("Failed to convert perspective camera to generic") 343 344 345def persp2genWmargin(pcam, ni, nj, margin, level=0): 346 batch.init_process("vpglConvertToGenericCameraWithMarginProcess") 347 batch.set_input_from_db(0, pcam) 348 batch.set_input_unsigned(1, ni) 349 batch.set_input_unsigned(2, nj) 350 batch.set_input_unsigned(3, level) 351 batch.set_input_int(4, margin) 352 batch.run_process() 353 (id, type) = batch.commit_output(0) 354 gcam = dbvalue(id, type) 355 (id, type) = batch.commit_output(1) 356 ni = batch.get_output_unsigned(id) 357 batch.remove_data(id) 358 (id, type) = batch.commit_output(2) 359 nj = batch.get_output_unsigned(id) 360 batch.remove_data(id) 361 (id, type) = batch.commit_output(3) 362 new_pers_cam = dbvalue(id, type) 363 return (gcam, ni, nj, new_pers_cam) 364 365 366def write_generic_to_vrml(cam, out_file_name, level=0): 367 batch.init_process("vpglWriteGenericCameraProcess") 368 batch.set_input_from_db(0, cam) 369 batch.set_input_string(1, out_file_name) 370 batch.set_input_unsigned(2, level) 371 batch.run_process() 372 373 374def get_generic_cam_ray(cam, u, v): 375 batch.init_process("vpglGetGenericCamRayProcess") 376 batch.set_input_from_db(0, cam) 377 batch.set_input_unsigned(1, u) 378 batch.set_input_unsigned(2, v) 379 batch.run_process() 380 (id, type) = batch.commit_output(0) 381 orig_x = batch.get_output_double(id) 382 batch.remove_data(id) 383 (id, type) = batch.commit_output(1) 384 orig_y = batch.get_output_double(id) 385 batch.remove_data(id) 386 (id, type) = batch.commit_output(2) 387 orig_z = batch.get_output_double(id) 388 batch.remove_data(id) 389 (id, type) = batch.commit_output(3) 390 dir_x = batch.get_output_double(id) 391 batch.remove_data(id) 392 (id, type) = batch.commit_output(4) 393 dir_y = batch.get_output_double(id) 394 batch.remove_data(id) 395 (id, type) = batch.commit_output(5) 396 dir_z = batch.get_output_double(id) 397 batch.remove_data(id) 398 return orig_x, orig_y, orig_z, dir_x, dir_y, dir_z 399 400# gets bounding box from a directory of cameras... (incomplete)_; 401def camera_dir_planar_bbox(dir_name): 402 batch.init_process("vpglGetBoundingBoxProcess") 403 batch.set_input_string(0, dir_name) 404 batch.run_process() 405 406 407def project_point(camera, x, y, z): 408 batch.init_process('vpglProjectProcess') 409 batch.set_input_from_db(0, camera) 410 batch.set_input_double(1, x) 411 batch.set_input_double(2, y) 412 batch.set_input_double(3, z) 413 batch.run_process() 414 (id, type) = batch.commit_output(0) 415 u = batch.get_output_double(id) 416 batch.remove_data(id) 417 (id, type) = batch.commit_output(1) 418 v = batch.get_output_double(id) 419 batch.remove_data(id) 420 return (u, v) 421 422# gets view direction at a point for a perspective camera; 423def get_view_at_point(persp_cam, x, y, z): 424 batch.init_process("vpglGetViewDirectionAtPointProcess") 425 batch.set_input_from_db(0, persp_cam) 426 batch.set_input_float(1, x) 427 batch.set_input_float(2, y) 428 batch.set_input_float(3, z) 429 batch.run_process() 430 (id, type) = batch.commit_output(0) 431 theta = batch.get_output_float(id) 432 batch.remove_data(id) 433 (id, type) = batch.commit_output(1) 434 phi = batch.get_output_float(id) 435 batch.remove_data(id) 436 return theta, phi 437 438 439def get_xyz_from_depth_image(cam, depth_img): 440 batch.init_process("vpglGenerateXYZFromDepthImageProcess") 441 batch.set_input_from_db(0, cam) # perspective or generic camera 442 batch.set_input_from_db(1, depth_img) 443 batch.run_process() 444 (id, type) = batch.commit_output(0) 445 x_img = dbvalue(id, type) 446 (id, type) = batch.commit_output(1) 447 y_img = dbvalue(id, type) 448 (id, type) = batch.commit_output(2) 449 z_img = dbvalue(id, type) 450 451 return x_img, y_img, z_img 452 453 454def get_3d_from_depth(cam, u, v, t): 455 batch.init_process("vpglGenerate3dPointFromDepthProcess") 456 batch.set_input_from_db(0, cam) # perspective or generic camera 457 batch.set_input_float(1, u) 458 batch.set_input_float(2, v) 459 batch.set_input_float(3, t) 460 batch.run_process() 461 (id, type) = batch.commit_output(0) 462 x = batch.get_output_float(id) 463 batch.remove_data(id) 464 (id, type) = batch.commit_output(1) 465 y = batch.get_output_float(id) 466 batch.remove_data(id) 467 (id, type) = batch.commit_output(2) 468 z = batch.get_output_float(id) 469 batch.remove_data(id) 470 return x, y, z 471 472# triangulates a list of cams and a list of points; 473def get_3d_from_cams(cams, points): 474 assert(len(cams) == len(points) and len(cams) > 1) 475 # list of points will just be [u1,v1,u2,v2...]; 476 ptlist = [] 477 for p in points: 478 ptlist.append(p[0]) 479 ptlist.append(p[1]) 480 # list of cam ids (type will be checked in C++); 481 camlist = [] 482 for cam in cams: 483 camlist.append(cam.id) 484 batch.init_process("vpglGenerate3dPointFromCamsProcess") 485 batch.set_input_unsigned_array(0, camlist) 486 batch.set_input_int_array(1, ptlist) 487 batch.run_process() 488 (id, type) = batch.commit_output(0) 489 x = batch.get_output_float(id) 490 batch.remove_data(id) 491 (id, type) = batch.commit_output(1) 492 y = batch.get_output_float(id) 493 batch.remove_data(id) 494 (id, type) = batch.commit_output(2) 495 z = batch.get_output_float(id) 496 batch.remove_data(id) 497 return x, y, z 498 499# create a generic camera; 500def convert_to_generic_camera(cam_in, ni, nj, level=0): 501 batch.init_process('vpglConvertToGenericCameraProcess') 502 batch.set_input_from_db(0, cam_in) 503 batch.set_input_unsigned(1, ni) 504 batch.set_input_unsigned(2, nj) 505 batch.set_input_unsigned(3, level) 506 status = batch.run_process() 507 generic_cam = None 508 if status: 509 (id, type) = batch.commit_output(0) 510 generic_cam = dbvalue(id, type) 511 return generic_cam 512 else: 513 raise VpglException("Failed to convert to generic camera") 514 515# create a generic camera from a local rational with user-specified z range; 516def convert_local_rational_to_generic(cam_in, ni, nj, min_z, max_z, level=0): 517 batch.init_process('vpglConvertLocalRationalToGenericProcess') 518 batch.set_input_from_db(0, cam_in) 519 batch.set_input_unsigned(1, ni) 520 batch.set_input_unsigned(2, nj) 521 batch.set_input_float(3, min_z) 522 batch.set_input_float(4, max_z) 523 batch.set_input_unsigned(5, level) 524 if not batch.run_process(): 525 return None 526 (id, type) = batch.commit_output(0) 527 generic_cam = dbvalue(id, type) 528 return generic_cam 529 530# correct a rational camera; 531def correct_rational_camera(cam_in, offset_x, offset_y, verbose = False): 532 batch.init_process('vpglCorrectRationalCameraProcess') 533 batch.set_input_from_db(0, cam_in) 534 batch.set_input_double(1, offset_x) 535 batch.set_input_double(2, offset_y) 536 batch.set_input_bool(3, verbose) 537 if not batch.run_process(): 538 return None 539 (id, type) = batch.commit_output(0) 540 corrected_cam = dbvalue(id, type) 541 return corrected_cam 542 543 544def get_rational_camera_offsets(cam_in): 545 batch.init_process('vpglGetRationalCameraOffsetsProcess') 546 batch.set_input_from_db(0, cam_in) 547 batch.run_process() 548 (id, type) = batch.commit_output(0) 549 offset_u = batch.get_output_double(id) 550 batch.remove_data(id) 551 (id, type) = batch.commit_output(1) 552 offset_v = batch.get_output_double(id) 553 batch.remove_data(id) 554 return (offset_u, offset_v) 555 556 557def get_correction_offset(cam_orig, cam_corrected): 558 offset_u, offset_v = get_rational_camera_offsets(cam_orig) 559 offset_u_c, offset_v_c = get_rational_camera_offsets(cam_corrected) 560 diff_u = offset_u_c - offset_u 561 diff_v = offset_v_c - offset_v 562 return diff_u, diff_v 563 564 565def find_offset_and_correct_rational_camera(cam_orig, cam_corrected, cam_to_be_corrected): 566 offset_u, offset_v = get_rational_camera_offsets(cam_orig) 567 offset_u_c, offset_v_c = get_rational_camera_offsets(cam_corrected) 568 diff_u = offset_u_c - offset_u 569 diff_v = offset_v_c - offset_v 570 cam_out = correct_rational_camera(cam_to_be_corrected, diff_u, diff_v) 571 return cam_out 572 573# convert lat,lon,el to local coordinates; 574def convert_to_local_coordinates(lvcs_filename, lat, lon, el): 575 batch.init_process('vpglConvertToLocalCoordinatesProcess') 576 batch.set_input_string(0, lvcs_filename) 577 batch.set_input_float(1, lat) 578 batch.set_input_float(2, lon) 579 batch.set_input_float(3, el) 580 batch.run_process() 581 (id, type) = batch.commit_output(0) 582 x = batch.get_output_float(id) 583 batch.remove_data(id) 584 (id, type) = batch.commit_output(1) 585 y = batch.get_output_float(id) 586 batch.remove_data(id) 587 (id, type) = batch.commit_output(2) 588 z = batch.get_output_float(id) 589 batch.remove_data(id) 590 return (x, y, z) 591 592# convert lat,lon,el to local coordinates; 593def convert_to_local_coordinates2(lvcs, lat, lon, el): 594 batch.init_process('vpglConvertToLocalCoordinatesProcess2') 595 batch.set_input_from_db(0, lvcs) 596 batch.set_input_double(1, lat) 597 batch.set_input_double(2, lon) 598 batch.set_input_double(3, el) 599 batch.run_process() 600 (id, type) = batch.commit_output(0) 601 x = batch.get_output_double(id) 602 batch.remove_data(id) 603 (id, type) = batch.commit_output(1) 604 y = batch.get_output_double(id) 605 batch.remove_data(id) 606 (id, type) = batch.commit_output(2) 607 z = batch.get_output_double(id) 608 batch.remove_data(id) 609 return (x, y, z) 610 611# convert lat,lon,el to local coordinates; 612def convert_local_to_global_coordinates(lvcs, x, y, z): 613 batch.init_process('vpglConvertLocalToGlobalCoordinatesProcess') 614 batch.set_input_from_db(0, lvcs) 615 batch.set_input_double(1, x) 616 batch.set_input_double(2, y) 617 batch.set_input_double(3, z) 618 batch.run_process() 619 (id, type) = batch.commit_output(0) 620 lat = batch.get_output_double(id) 621 batch.remove_data(id) 622 (id, type) = batch.commit_output(1) 623 lon = batch.get_output_double(id) 624 batch.remove_data(id) 625 (id, type) = batch.commit_output(2) 626 el = batch.get_output_double(id) 627 batch.remove_data(id) 628 return (lat, lon, el) 629 630# convert lat,lon,el to local coordinates; 631def convert_local_to_global_coordinates_array(lvcs, x, y, z): 632 batch.init_process('vpglConvertLocalToGlobalCoordinatesArrayProcess') 633 batch.set_input_from_db(0, lvcs) 634 batch.set_input_double_array(1, x) 635 batch.set_input_double_array(2, y) 636 batch.set_input_double_array(3, z) 637 batch.run_process() 638 (id, type) = batch.commit_output(0) 639 lat = batch.get_output_double_array(id) 640 batch.remove_data(id) 641 (id, type) = batch.commit_output(1) 642 lon = batch.get_output_double_array(id) 643 batch.remove_data(id) 644 (id, type) = batch.commit_output(2) 645 el = batch.get_output_double_array(id) 646 batch.remove_data(id) 647 return (lat, lon, el) 648 649# convert lat,lon,el to local coordinates; 650def create_lvcs(lat, lon, el, csname): 651 batch.init_process('vpglCreateLVCSProcess') 652 batch.set_input_double(0, lat) 653 batch.set_input_double(1, lon) 654 batch.set_input_double(2, el) 655 batch.set_input_string(3, csname) 656 batch.run_process() 657 (id, type) = batch.commit_output(0) 658 lvcs = dbvalue(id, type) 659 return lvcs 660 661# randomly sample a camera rotated around principal axis; 662def perturb_camera(cam_in, angle, rng): 663 batch.init_process('vpglPerturbPerspCamOrientProcess') 664 batch.set_input_from_db(0, cam_in) 665 batch.set_input_float(1, angle) 666 batch.set_input_from_db(2, rng) 667 batch.run_process() 668 (id, type) = batch.commit_output(0) 669 pert_cam = dbvalue(id, type) 670 (theta_id, type) = batch.commit_output(1) 671 (phi_id, type) = batch.commit_output(2) 672 theta = batch.get_output_float(theta_id) 673 phi = batch.get_output_float(phi_id) 674 batch.remove_data(theta_id) 675 batch.remove_data(phi_id) 676 return pert_cam, theta, phi 677 678 679def write_perspective_cam_vrml(vrml_filename, pcam, camera_rad, axis_length, r, g, b): 680 batch.init_process("bvrmlWritePerspectiveCamProcess") 681 batch.set_input_string(0, vrml_filename) 682 batch.set_input_from_db(1, pcam) 683 batch.set_input_float(2, camera_rad) 684 batch.set_input_float(3, axis_length) 685 batch.set_input_float(4, r) 686 batch.set_input_float(5, g) 687 batch.set_input_float(6, b) 688 batch.run_process() 689 690# rotate a camera around principal axis; 691def rotate_perspective_camera(cam_in, theta, phi): 692 batch.init_process('vpglRotatePerspCamProcess') 693 batch.set_input_from_db(0, cam_in) 694 batch.set_input_float(1, theta) 695 batch.set_input_float(2, phi) 696 batch.run_process() 697 (id, type) = batch.commit_output(0) 698 rot_cam = dbvalue(id, type) 699 return rot_cam 700 701 702def get_perspective_cam_center(pcam): 703 batch.init_process("vpglGetPerspectiveCamCenterProcess") 704 batch.set_input_from_db(0, pcam) 705 batch.run_process() 706 (x_id, x_type) = batch.commit_output(0) 707 x = batch.get_output_float(x_id) 708 batch.remove_data(x_id) 709 (y_id, type) = batch.commit_output(1) 710 y = batch.get_output_float(y_id) 711 batch.remove_data(y_id) 712 (z_id, type) = batch.commit_output(2) 713 z = batch.get_output_float(z_id) 714 batch.remove_data(z_id) 715 return x, y, z 716 717 718def create_perspective_camera2(pcam, cent_x, cent_y, cent_z): 719 batch.init_process("vpglCreatePerspectiveCameraProcess2") 720 batch.set_input_from_db(0, pcam) 721 batch.set_input_float(1, cent_x) 722 batch.set_input_float(2, cent_y) 723 batch.set_input_float(3, cent_z) 724 batch.run_process() 725 (c_id, c_type) = batch.commit_output(0) 726 cam = dbvalue(c_id, c_type) 727 return cam 728 729 730def create_perspective_camera_with_rot(pcam, phi, theta, cent_x, cent_y, cent_z): 731 batch.init_process("vpglCreatePerspectiveCameraProcess3") 732 batch.set_input_from_db(0, pcam) 733 batch.set_input_float(1, phi) 734 batch.set_input_float(2, theta) 735 batch.set_input_float(3, cent_x) 736 batch.set_input_float(4, cent_y) 737 batch.set_input_float(5, cent_z) 738 batch.run_process() 739 (c_id, c_type) = batch.commit_output(0) 740 cam = dbvalue(c_id, c_type) 741 return cam 742 743 744def get_nitf_footprint(nitf_list_filename, out_kml_filename): 745 batch.init_process('vpglNITFFootprintProcess') 746 batch.set_input_string(0, nitf_list_filename) 747 batch.set_input_string(1, out_kml_filename) 748 batch.run_process() 749 750 751def get_single_nitf_footprint(nitf_filename, out_kml_filename="", isKml=False, metafolder=""): 752 batch.init_process('vpglNITFFootprintProcess2') 753 batch.set_input_string(0, nitf_filename) 754 batch.set_input_string(1, out_kml_filename) 755 batch.set_input_bool(2, isKml) 756 batch.set_input_string(3, metafolder) 757 batch.run_process() 758 (id, type) = batch.commit_output(0) 759 llon = batch.get_output_double(id) 760 (id, type) = batch.commit_output(1) 761 llat = batch.get_output_double(id) 762 (id, type) = batch.commit_output(2) 763 lele = batch.get_output_double(id) 764 (id, type) = batch.commit_output(3) 765 rlon = batch.get_output_double(id) 766 (id, type) = batch.commit_output(4) 767 rlat = batch.get_output_double(id) 768 (id, type) = batch.commit_output(5) 769 rele = batch.get_output_double(id) 770 batch.remove_data(id) 771 return llon, llat, lele, rlon, rlat, rele 772 773# use a local lvcs to calculate GSD of nitf image 774def calculate_nitf_gsd(rational_cam, lon1, lat1, elev1, distance=1000.0): 775 # create a local lvcs 776 lvcs = create_lvcs(lat1, lon1, elev1, 'wgs84') 777 lat2, lon2, elev2 = convert_local_to_global_coordinates( 778 lvcs, distance, distance, 0.0) 779 # calculate image pixel difference 780 i1, j1 = project_point(rational_cam, lon1, lat1, elev1) 781 i2, j2 = project_point(rational_cam, lon2, lat2, elev2) 782 gsd_i = distance / (i2 - i1) 783 gsd_j = distance / (j2 - j1) 784 if (gsd_i < 0.0): 785 gsd_i = -1 * gsd_i 786 if (gsd_j < 0.0): 787 gsd_j = -1 * gsd_j 788 batch.remove_data(lvcs.id) 789 return gsd_i, gsd_j 790 791def get_geocam_footprint_with_value(geocam, geotiff_filename, out_kml_filename="", write_kml=False): 792 batch.init_process("vpglGeoFootprintProcess2") 793 batch.set_input_from_db(0, geocam) 794 batch.set_input_string(1, geotiff_filename) 795 batch.set_input_string(2, out_kml_filename) 796 batch.set_input_bool(3, write_kml) 797 status = batch.run_process() 798 if status: 799 (id, type) = batch.commit_output(0) 800 ll_lon = batch.get_output_double(id) 801 (id, type) = batch.commit_output(1) 802 ll_lat = batch.get_output_double(id) 803 (id, type) = batch.commit_output(2) 804 ur_lon = batch.get_output_double(id) 805 (id, type) = batch.commit_output(3) 806 ur_lat = batch.get_output_double(id) 807 return ll_lon, ll_lat, ur_lon, ur_lat 808 else: 809 raise VpglException("Failed to get geographic camera footprint") 810 811 812def load_geotiff_cam(tfw_filename, lvcs=0, utm_zone=0, utm_hemisphere=0): 813 batch.init_process("vpglLoadGeoCameraProcess") 814 batch.set_input_string(0, tfw_filename) 815 if lvcs != 0: 816 batch.set_input_from_db(1, lvcs) 817 batch.set_input_int(2, utm_zone) 818 batch.set_input_unsigned(3, utm_hemisphere) 819 batch.run_process() 820 (c_id, c_type) = batch.commit_output(0) 821 cam = dbvalue(c_id, c_type) 822 return cam 823 824 825def save_geocam_to_tfw(cam, tfw_filename): 826 batch.init_process("vpglSaveGeoCameraTFWProcess") 827 batch.set_input_from_db(0, cam) 828 batch.set_input_string(1, tfw_filename) 829 batch.run_process() 830 831 832def get_geotransform(cam): 833 batch.init_process("vpglGetGeoTransformProcess") 834 batch.set_input_from_db(0, cam) 835 status = batch.run_process() 836 if status: 837 GT = [None]*6 838 for idx,gt in enumerate(GT): 839 (id, type) = batch.commit_output(idx) 840 GT[idx] = batch.get_output_double(id) 841 batch.remove_data(id) 842 return GT 843 else: 844 raise VpglException("Failed to return geotransform") 845 846 847def load_geotiff_cam2(filename, ni, nj): 848 batch.init_process("vpglLoadGeoCameraProcess2") 849 batch.set_input_string(0, filename) 850 batch.set_input_unsigned(1, ni) 851 batch.set_input_unsigned(2, nj) 852 batch.run_process() 853 (c_id, c_type) = batch.commit_output(0) 854 cam = dbvalue(c_id, c_type) 855 return cam 856 857 858def load_geotiff_from_header(filename, lvcs=0): 859 batch.init_process("vpglLoadGeotiffCamFromHeaderProcess") 860 batch.set_input_string(0, filename) 861 if lvcs != 0: 862 batch.set_input_from_db(1, lvcs) 863 batch.run_process() 864 (c_id, c_type) = batch.commit_output(0) 865 cam = dbvalue(c_id, c_type) 866 return cam 867 868 869def translate_geo_camera(geocam, x, y): 870 batch.init_process("vpglTranslateGeoCameraProcess") 871 batch.set_input_from_db(0, geocam) 872 batch.set_input_double(1, x) 873 batch.set_input_double(2, y) 874 batch.run_process() 875 (c_id, c_type) = batch.commit_output(0) 876 cam = dbvalue(c_id, c_type) 877 return cam 878 879 880def create_geotiff_cam(ll_lon, ll_lat, ur_lon, ur_lat, ni, nj, lvcs=0): 881 batch.init_process("vpglCreateGeoCameraProcess") 882 batch.set_input_double(0, ll_lon) 883 batch.set_input_double(1, ll_lat) 884 batch.set_input_double(2, ur_lon) 885 batch.set_input_double(3, ur_lat) 886 batch.set_input_unsigned(4, ni) 887 batch.set_input_unsigned(5, nj) 888 if lvcs != 0: 889 batch.set_input_from_db(6, lvcs) 890 status = batch.run_process() 891 if status: 892 (id, type) = batch.commit_output(0) 893 cam = dbvalue(id, type) 894 return cam 895 else: 896 raise VpglException("Failed to create geotiff camera") 897 898 899def geo2generic(geocam, ni, nj, scene_height, level): 900 batch.init_process("vpglConvertGeoCameraToGenericProcess") 901 batch.set_input_from_db(0, geocam) 902 batch.set_input_int(1, ni) 903 batch.set_input_int(2, nj) 904 batch.set_input_double(3, scene_height) 905 batch.set_input_int(4, level) 906 batch.run_process() 907 (c_id, c_type) = batch.commit_output(0) 908 cam = dbvalue(c_id, c_type) 909 return cam 910 911 912def geo2generic_nonnadir(geocam, ni, nj, scene_height, dir_x, dir_y, dir_z, level): 913 batch.init_process("vpglConvertNonNadirGeoCameraToGenericProcess") 914 batch.set_input_from_db(0, geocam) 915 batch.set_input_int(1, ni) 916 batch.set_input_int(2, nj) 917 batch.set_input_double(3, scene_height) 918 batch.set_input_int(4, level) 919 batch.set_input_double(5, dir_x) 920 batch.set_input_double(6, dir_y) 921 batch.set_input_double(7, dir_z) 922 batch.run_process() 923 (c_id, c_type) = batch.commit_output(0) 924 cam = dbvalue(c_id, c_type) 925 return cam 926 927 928def save_lvcs(lvcs, lvcs_filename): 929 batch.init_process("vpglSaveLVCSProcess") 930 batch.set_input_from_db(0, lvcs) 931 batch.set_input_string(1, lvcs_filename) 932 return batch.run_process() 933 934 935def create_and_save_lvcs(lat, lon, elev, cs_name, lvcs_filename): 936 batch.init_process("vpglCreateAndSaveLVCSProcess") 937 batch.set_input_float(0, lat) 938 batch.set_input_float(1, lon) 939 batch.set_input_float(2, elev) 940 batch.set_input_string(3, cs_name) 941 batch.set_input_string(4, lvcs_filename) 942 return batch.run_process() 943 944 945def load_lvcs(lvcs_filename): 946 batch.init_process("vpglLoadLVCSProcess") 947 batch.set_input_string(0, lvcs_filename) 948 batch.run_process() 949 (lvcs_id, lvcs_type) = batch.commit_output(0) 950 lvcs = dbvalue(lvcs_id, lvcs_type) 951 return lvcs 952 953 954def geo_cam_global_to_img(geocam, lon, lat): 955 batch.init_process("vpglGeoGlobalToImgProcess") 956 batch.set_input_from_db(0, geocam) 957 batch.set_input_double(1, lon) 958 batch.set_input_double(2, lat) 959 batch.run_process() 960 (id, type) = batch.commit_output(0) 961 u = batch.get_output_int(id) 962 batch.remove_data(id) 963 (id, type) = batch.commit_output(1) 964 v = batch.get_output_int(id) 965 batch.remove_data(id) 966 return u, v 967 968 969def geo_cam_img_to_global(geocam, i, j): 970 batch.init_process("vpglGeoImgToGlobalProcess") 971 batch.set_input_from_db(0, geocam) 972 batch.set_input_unsigned(1, i) 973 batch.set_input_unsigned(2, j) 974 status = batch.run_process() 975 if status: 976 (id, type) = batch.commit_output(0) 977 lon = batch.get_output_double(id) 978 (id, type) = batch.commit_output(1) 979 lat = batch.get_output_double(id) 980 return lon, lat 981 else: 982 raise VpglException("Failed to convert geographic camera image to global") 983 984 985def convert_perspective_to_nvm(cams_dir, imgs_dir, output_nvm): 986 batch.init_process("vpglExportCamerasToNvmProcess") 987 batch.set_input_string(0, cams_dir) 988 batch.set_input_string(1, imgs_dir) 989 batch.set_input_string(2, output_nvm) 990 return batch.run_process() 991 992 993def interpolate_perspective_cameras(cam0, cam1, ncams, outdir): 994 batch.init_process("vpglInterpolatePerspectiveCamerasProcess") 995 batch.set_input_from_db(0, cam0) 996 batch.set_input_from_db(1, cam1) 997 batch.set_input_unsigned(2, ncams) 998 batch.set_input_string(3, outdir) 999 return batch.run_process() 1000 1001 1002def compute_affine_from_local_rational(cropped_cam, min_x, min_y, min_z, max_x, max_y, max_z, n_points=100): 1003 batch.init_process("vpglComputeAffineFromRationalProcess") 1004 batch.set_input_from_db(0, cropped_cam) 1005 batch.set_input_double(1, min_x) 1006 batch.set_input_double(2, min_y) 1007 batch.set_input_double(3, min_z) 1008 batch.set_input_double(4, max_x) 1009 batch.set_input_double(5, max_y) 1010 batch.set_input_double(6, max_z) 1011 batch.set_input_unsigned(7, n_points) 1012 status = batch.run_process() 1013 if status: 1014 (id, type) = batch.commit_output(0) 1015 out_cam = dbvalue(id, type) 1016 return out_cam 1017 else: 1018 raise VpglException("Failed to compute affine from rational camera") 1019 1020# use the affine cameras of the images to compute an affine fundamental matrix and rectify them (flatten epipolar lines to scan lines and align them) 1021# use the 3-d box that the cameras see to compute correspondences for 1022# minimally distortive alignment 1023def affine_rectify_images(img1, affine_cam1, img2, affine_cam2, min_x, min_y, min_z, max_x, max_y, max_z, local_ground_plane_height=5, n_points=100): 1024 batch.init_process("vpglAffineRectifyImagesProcess") 1025 batch.set_input_from_db(0, img1) 1026 batch.set_input_from_db(1, affine_cam1) 1027 batch.set_input_from_db(2, img2) 1028 batch.set_input_from_db(3, affine_cam2) 1029 batch.set_input_double(4, min_x) 1030 batch.set_input_double(5, min_y) 1031 batch.set_input_double(6, min_z) 1032 batch.set_input_double(7, max_x) 1033 batch.set_input_double(8, max_y) 1034 batch.set_input_double(9, max_z) 1035 batch.set_input_unsigned(10, n_points) 1036 batch.set_input_double(11, local_ground_plane_height) 1037 batch.run_process() 1038 (id, type) = batch.commit_output(0) 1039 out_img1 = dbvalue(id, type) 1040 (id, type) = batch.commit_output(1) 1041 out_cam1 = dbvalue(id, type) 1042 (id, type) = batch.commit_output(2) 1043 out_img2 = dbvalue(id, type) 1044 (id, type) = batch.commit_output(3) 1045 out_cam2 = dbvalue(id, type) 1046 return out_img1, out_cam1, out_img2, out_cam2 1047 1048# use the affine cameras of the images to compute an affine fundamental matrix and rectify them (flatten epipolar lines to scan lines and align them) 1049# use the 3-d box that the cameras see to compute correspondences for 1050# minimally distortive alignment, use the local rational cameras to find 1051# the correspondence points 1052def affine_rectify_images2(img1, affine_cam1, local_rational_cam1, img2, affine_cam2, local_rational_cam2, min_x, min_y, min_z, max_x, max_y, max_z, output_path_H1, output_path_H2, local_ground_plane_height=5, n_points=100): 1053 batch.init_process("vpglAffineRectifyImagesProcess2") 1054 batch.set_input_from_db(0, img1) 1055 batch.set_input_from_db(1, affine_cam1) 1056 batch.set_input_from_db(2, local_rational_cam1) 1057 batch.set_input_from_db(3, img2) 1058 batch.set_input_from_db(4, affine_cam2) 1059 batch.set_input_from_db(5, local_rational_cam2) 1060 batch.set_input_double(6, min_x) 1061 batch.set_input_double(7, min_y) 1062 batch.set_input_double(8, min_z) 1063 batch.set_input_double(9, max_x) 1064 batch.set_input_double(10, max_y) 1065 batch.set_input_double(11, max_z) 1066 batch.set_input_unsigned(12, n_points) 1067 batch.set_input_double(13, local_ground_plane_height) 1068 batch.set_input_string(14, output_path_H1) 1069 batch.set_input_string(15, output_path_H2) 1070 status = batch.run_process() 1071 if status: 1072 (id, type) = batch.commit_output(0) 1073 out_img1 = dbvalue(id, type) 1074 (id, type) = batch.commit_output(1) 1075 out_cam1 = dbvalue(id, type) 1076 (id, type) = batch.commit_output(2) 1077 out_img2 = dbvalue(id, type) 1078 (id, type) = batch.commit_output(3) 1079 out_cam2 = dbvalue(id, type) 1080 return out_img1, out_cam1, out_img2, out_cam2 1081 else: 1082 raise VpglException("Image rectification from affine cameras failed") 1083 1084 1085# use the affine cameras of the images to compute an affine fundamental 1086# matrix and write the f matrix out 1087def affine_f_matrix(affine_cam1, affine_cam2, output_path): 1088 batch.init_process("vpglAffineFMatrixProcess") 1089 batch.set_input_from_db(0, affine_cam1) 1090 batch.set_input_from_db(1, affine_cam2) 1091 batch.set_input_string(2, output_path) 1092 batch.run_process() 1093 1094 1095def construct_height_map_from_disparity(img1, img1_disp, min_disparity, local_rational_cam1, img2, local_rational_cam2, 1096 min_x, min_y, min_z, max_x, max_y, max_z, path_H1, path_H2, voxel_size, 1097 z_offset = 0.0): 1098 batch.init_process("vpglConstructHeightMapProcess") 1099 batch.set_input_from_db(0, img1) 1100 batch.set_input_from_db(1, local_rational_cam1) 1101 batch.set_input_from_db(2, img1_disp) 1102 batch.set_input_float(3, min_disparity) 1103 batch.set_input_from_db(4, img2) 1104 batch.set_input_from_db(5, local_rational_cam2) 1105 batch.set_input_double(6, min_x) 1106 batch.set_input_double(7, min_y) 1107 batch.set_input_double(8, min_z) 1108 batch.set_input_double(9, max_x) 1109 batch.set_input_double(10, max_y) 1110 batch.set_input_double(11, max_z) 1111 batch.set_input_double(12, voxel_size) 1112 batch.set_input_string(13, path_H1) 1113 batch.set_input_string(14, path_H2) 1114 batch.set_input_double(15, z_offset) 1115 status = batch.run_process() 1116 if status: 1117 (id, type) = batch.commit_output(0) 1118 out_map = dbvalue(id, type) 1119 (id, type) = batch.commit_output(1) 1120 disparity_map = dbvalue(id, type) 1121 return out_map, disparity_map 1122 else: 1123 raise VpglException("DSM from Disparity failed") 1124 1125 1126 1127def compute_camera_to_world_homography(cam, plane, inverse=False): 1128 batch.init_process("vpglComputeImageToWorldHomographyProcess") 1129 batch.set_input_from_db(0, cam) 1130 batch.set_input_float_array(1, plane) 1131 batch.set_input_bool(2, inverse) 1132 batch.run_process() 1133 (id, type) = batch.commit_output(0) 1134 homg2d = batch.get_bbas_1d_array_float(id) 1135 batch.remove_data(id) 1136 return homg2d 1137 1138# use the 3-d box to crop an image using image camera, given certain uncertainty value in meter unit 1139# note that the input 3-d box is in unit of wgs84 geo coordinates 1140def crop_image_using_3d_box(img_res_ni, img_res_nj, camera, lower_left_lon, lower_left_lat, lower_left_elev, upper_right_lon, upper_right_lat, upper_right_elev, uncertainty, lvcs=0): 1141 batch.init_process("vpglCropImgUsing3DboxProcess") 1142 batch.set_input_unsigned(0, img_res_ni) 1143 batch.set_input_unsigned(1, img_res_nj) 1144 batch.set_input_from_db(2, camera) 1145 batch.set_input_double(3, lower_left_lon) 1146 batch.set_input_double(4, lower_left_lat) 1147 batch.set_input_double(5, lower_left_elev) 1148 batch.set_input_double(6, upper_right_lon) 1149 batch.set_input_double(7, upper_right_lat) 1150 batch.set_input_double(8, upper_right_elev) 1151 batch.set_input_double(9, uncertainty) 1152 if lvcs: 1153 batch.set_input_from_db(10, lvcs) 1154 status = batch.run_process() 1155 if status: 1156 (id, type) = batch.commit_output(0) 1157 local_cam = dbvalue(id, type) 1158 (id, type) = batch.commit_output(1) 1159 i0 = batch.get_output_unsigned(id) 1160 batch.remove_data(id) 1161 (id, type) = batch.commit_output(2) 1162 j0 = batch.get_output_unsigned(id) 1163 batch.remove_data(id) 1164 (id, type) = batch.commit_output(3) 1165 ni = batch.get_output_unsigned(id) 1166 batch.remove_data(id) 1167 (id, type) = batch.commit_output(4) 1168 nj = batch.get_output_unsigned(id) 1169 batch.remove_data(id) 1170 return status, local_cam, i0, j0, ni, nj 1171 else: 1172 raise VpglException("Failed to crop image using 3D box") 1173 1174 1175# use the 3-d box to crop an image using image camera, given certain uncertainty value in meter unit 1176# note that the elevation of 3-d box is obtained from DEM height map 1177def crop_image_using_3d_box_dem(img_res, camera, ll_lon, ll_lat, ur_lon, ur_lat, dem_folder, extra_height, uncertainty, lvcs=0): 1178 batch.init_process("vpglCropImgUsing3DboxDemProcess") 1179 batch.set_input_from_db(0, img_res) 1180 batch.set_input_from_db(1, camera) 1181 batch.set_input_double(2, ll_lon) 1182 batch.set_input_double(3, ll_lat) 1183 batch.set_input_double(4, ur_lon) 1184 batch.set_input_double(5, ur_lat) 1185 batch.set_input_string(6, dem_folder) 1186 batch.set_input_double(7, extra_height) 1187 batch.set_input_double(8, uncertainty) 1188 if lvcs != 0: 1189 batch.set_input_from_db(9, lvcs) 1190 status = batch.run_process() 1191 if status: 1192 (id, type) = batch.commit_output(0) 1193 local_cam = dbvalue(id, type) 1194 (id, type) = batch.commit_output(1) 1195 i0 = batch.get_output_unsigned(id) 1196 (id, type) = batch.commit_output(2) 1197 j0 = batch.get_output_unsigned(id) 1198 (id, type) = batch.commit_output(3) 1199 ni = batch.get_output_unsigned(id) 1200 (id, type) = batch.commit_output(4) 1201 nj = batch.get_output_unsigned(id) 1202 return status, local_cam, i0, j0, ni, nj 1203 else: 1204 raise VpglException("Failed to crop image using 3D box DEM") 1205 1206# use the 3-d box to crop an ortho image using its geo camera 1207# note that the input 3-d box is in unit of wgs84 geo coordinates 1208def crop_ortho_image_using_3d_box(img_res, camera, lower_left_lon, lower_left_lat, lower_left_elev, upper_right_lon, upper_right_lat, upper_right_elev): 1209 batch.init_process("vpglCropOrthoUsing3DboxPRocess") 1210 batch.set_input_from_db(0, img_res) 1211 batch.set_input_from_db(1, camera) 1212 batch.set_input_double(2, lower_left_lon) 1213 batch.set_input_double(3, lower_left_lat) 1214 batch.set_input_double(4, lower_left_elev) 1215 batch.set_input_double(5, upper_right_lon) 1216 batch.set_input_double(6, upper_right_lat) 1217 batch.set_input_double(7, upper_right_elev) 1218 status = batch.run_process() 1219 if status: 1220 (id, type) = batch.commit_output(0) 1221 local_geo_cam = dbvalue(id, type) 1222 (id, type) = batch.commit_output(1) 1223 i0 = batch.get_output_unsigned(id) 1224 (id, type) = batch.commit_output(2) 1225 j0 = batch.get_output_unsigned(id) 1226 (id, type) = batch.commit_output(3) 1227 ni = batch.get_output_unsigned(id) 1228 (id, type) = batch.commit_output(4) 1229 nj = batch.get_output_unsigned(id) 1230 return status, local_geo_cam, i0, j0, ni, nj 1231 else: 1232 raise VpglException("Failed to crop ortho image using 3D box") 1233 1234 1235# use the 3-d box to offset the local camera using image camera, given certain uncertainty value in meter unit 1236# note that the input 3-d box is in unit of wgs84 geo coordinates 1237def offset_cam_using_3d_box(camera, lower_left_lon, lower_left_lat, lower_left_elev, upper_right_lon, upper_right_lat, upper_right_elev, uncertainty, lvcs=None): 1238 batch.init_process("vpglOffsetCamUsing3DboxProcess") 1239 batch.set_input_from_db(0, camera) 1240 batch.set_input_double(1, lower_left_lon) 1241 batch.set_input_double(2, lower_left_lat) 1242 batch.set_input_double(3, lower_left_elev) 1243 batch.set_input_double(4, upper_right_lon) 1244 batch.set_input_double(5, upper_right_lat) 1245 batch.set_input_double(6, upper_right_elev) 1246 batch.set_input_double(7, uncertainty) 1247 if lvcs: 1248 batch.set_input_from_db(8, lvcs) 1249 status = batch.run_process() 1250 if status: 1251 (id, type) = batch.commit_output(0) 1252 local_cam = dbvalue(id, type) 1253 (id, type) = batch.commit_output(1) 1254 i0 = batch.get_output_unsigned(id) 1255 batch.remove_data(id) 1256 (id, type) = batch.commit_output(2) 1257 j0 = batch.get_output_unsigned(id) 1258 batch.remove_data(id) 1259 (id, type) = batch.commit_output(3) 1260 ni = batch.get_output_unsigned(id) 1261 batch.remove_data(id) 1262 (id, type) = batch.commit_output(4) 1263 nj = batch.get_output_unsigned(id) 1264 batch.remove_data(id) 1265 return status, local_cam, i0, j0, ni, nj 1266 else: 1267 raise VpglException("Failed to offset camera using 3D box") 1268 1269 1270# covert (lat, lon) to UTM coordinates 1271def utm_coords(lon, lat): 1272 batch.init_process("vpglComputeUTMZoneProcess") 1273 batch.set_input_double(0, lon) 1274 batch.set_input_double(1, lat) 1275 result = batch.run_process() 1276 if result: 1277 (id, type) = batch.commit_output(0) 1278 x = batch.get_output_double(id) 1279 (id, type) = batch.commit_output(1) 1280 y = batch.get_output_double(id) 1281 (id, type) = batch.commit_output(2) 1282 utm_zone = batch.get_output_int(id) 1283 (id, type) = batch.commit_output(3) 1284 northing = batch.get_output_int(id) 1285 return x, y, utm_zone, northing 1286 else: 1287 return 0.0, 0.0, 0, 0 1288 1289 1290# get the world point (wgs84) given the image point and rational camera 1291# Pass default initial guess point (-1.0, -1.0, -1.0) and plane height 1292# (-1.0) if initial is unknown at all 1293def rational_cam_img_to_global(camera, i, j, init_lon=-1.0, init_lat=-1.0, init_elev=-1.0, pl_elev=-1.0, error_tol=0.05): 1294 batch.init_process("vpglRationalImgToGlobalProcess") 1295 batch.set_input_from_db(0, camera) 1296 batch.set_input_unsigned(1, i) 1297 batch.set_input_unsigned(2, j) 1298 batch.set_input_double(3, init_lon) 1299 batch.set_input_double(4, init_lat) 1300 batch.set_input_double(5, init_elev) 1301 batch.set_input_double(6, pl_elev) 1302 batch.set_input_double(7, error_tol) 1303 status = batch.run_process() 1304 if status: 1305 (id, type) = batch.commit_output(0) 1306 lon = batch.get_output_double(id) 1307 (id, type) = batch.commit_output(1) 1308 lat = batch.get_output_double(id) 1309 (id, type) = batch.commit_output(2) 1310 elev = batch.get_output_double(id) 1311 return lon, lat, elev 1312 else: 1313 raise VpglException("Failed to convert rational camera image to global") 1314 1315 1316def rational_cam_nadirness(camera, lat, lon, elev): 1317 batch.init_process("vpglRationalCamNadirnessProcess") 1318 batch.set_input_from_db(0, camera) 1319 batch.set_input_double(1, lat) 1320 batch.set_input_double(2, lon) 1321 batch.set_input_double(3, elev) 1322 batch.run_process() 1323 (id, type) = batch.commit_output(0) 1324 val = batch.get_output_double(id) 1325 return val 1326 1327 1328# calculate GSD from a rational camera 1329def calculate_nitf_gsd(rational_cam, lon1, lat1, elev1, distance=1000): 1330 # create a lvcs 1331 lvcs = create_lvcs(lat1, lon1, elev1, "wgs84") 1332 lat2, lon2, elev2 = convert_local_to_global_coordinates( 1333 lvcs, distance, distance, 0.0) 1334 # calculate image pixel 1335 i1, j1 = project_point(rational_cam, lon1, lat1, elev1) 1336 i2, j2 = project_point(rational_cam, lon2, lat2, elev2) 1337 gsd_i = distance / (i2 - i1) 1338 gsd_j = distance / (j2 - j1) 1339 if (gsd_i < 0.0): 1340 gsd_i = -1 * gsd_i 1341 if (gsd_j < 0.0): 1342 gsd_j = -1 * gsd_j 1343 batch.remove_data(lvcs.id) 1344 return gsd_i, gsd_j 1345 1346 1347# geo-register series of rational cameras using their correspondence features 1348def isfm_rational_camera(trackfile, output_folder, pixel_radius): 1349 batch.init_process("vpglIsfmRationalCameraProcess") 1350 batch.set_input_string(0, trackfile) 1351 batch.set_input_string(1, output_folder) 1352 # pixel radius to count for inliers 1353 batch.set_input_float(2, pixel_radius) 1354 if not batch.run_process(): 1355 return None, -1.0, -1.0 1356 (id, type) = batch.commit_output(0) 1357 cam = dbvalue(id, type) 1358 (id, type) = batch.commit_output(1) 1359 error = batch.get_output_float(id) 1360 (id, type) = batch.commit_output(2) 1361 inliers = batch.get_output_float(id) 1362 return cam, error, inliers 1363 1364 1365# geo-register a rational camera to group of geo-registered cameras 1366def isfm_rational_camera_seed(track_file, out_folder, 1367 ll_lon, ll_lat, ll_elev, 1368 ur_lon, ur_lat, ur_elev, 1369 pixel_radius=2.0, enforce_existing=False, 1370 verbose = False, 1371 ): 1372 batch.init_process("vpglIsfmRationalCameraSeedProcess") 1373 batch.set_input_string(0, track_file) 1374 batch.set_input_string(1, out_folder) 1375 batch.set_input_double(2, ll_lon) 1376 batch.set_input_double(3, ll_lat) 1377 batch.set_input_double(4, ll_elev) 1378 batch.set_input_double(5, ur_lon) 1379 batch.set_input_double(6, ur_lat) 1380 batch.set_input_double(7, ur_elev) 1381 batch.set_input_double(8, pixel_radius) 1382 batch.set_input_bool(9, enforce_existing) 1383 batch.set_input_bool(10, verbose) 1384 1385 status = batch.run_process() 1386 return status 1387 1388 1389def isfm_rational_camera_with_init(track_file, 1390 ll_lon, ll_lat, ll_elev, 1391 ur_lon, ur_lat, ur_elev, 1392 pixel_radius=2.0, 1393 verbose = False, 1394 ): 1395 batch.init_process("vpglIsfmRationalCameraWithInitialProcess") 1396 batch.set_input_string(0, track_file) 1397 batch.set_input_double(1, ll_lon) 1398 batch.set_input_double(2, ll_lat) 1399 batch.set_input_double(3, ll_elev) 1400 batch.set_input_double(4, ur_lon) 1401 batch.set_input_double(5, ur_lat) 1402 batch.set_input_double(6, ur_elev) 1403 batch.set_input_double(7, pixel_radius) 1404 batch.set_input_bool(8, verbose) 1405 1406 if not batch.run_process(): 1407 return None, -1.0, -1.0 1408 (id, type) = batch.commit_output(0) 1409 cam = dbvalue(id, type) 1410 (id, type) = batch.commit_output(1) 1411 error = batch.get_output_double(id) 1412 batch.remove_data(id) 1413 (id, type) = batch.commit_output(2) 1414 inliers = batch.get_output_double(id) 1415 batch.remove_data(id) 1416 return cam, error, inliers 1417 1418 1419# rotate a camera around principle axis 1420 1421 1422def perspective_camera_distance(cam1, cam2): 1423 batch.init_process('vpglPerspCamDistanceProcess') 1424 batch.set_input_from_db(0, cam1) 1425 batch.set_input_from_db(1, cam2) 1426 batch.run_process() 1427 (dist_id, type) = batch.commit_output(0) 1428 dist = batch.get_output_float(dist_id) 1429 return dist 1430 1431 1432def correct_cam_rotation(img, pcam, exp_img, cone_half_angle, n_steps, refine=True): 1433 batch.init_process('icamCorrectCamRotationProcess') 1434 batch.set_input_from_db(0, img) 1435 batch.set_input_from_db(1, pcam) 1436 batch.set_input_from_db(2, exp_img) 1437 batch.set_input_float(3, cone_half_angle) 1438 batch.set_input_unsigned(4, n_steps) 1439 batch.set_input_bool(5, refine) 1440 batch.run_process() 1441 (m_id, m_type) = batch.commit_output(0) 1442 mapped_img = dbvalue(m_id, m_type) 1443 (c_id, c_type) = batch.commit_output(1) 1444 corr_cam = dbvalue(c_id, c_type) 1445 return mapped_img, corr_cam 1446 1447 1448def compute_direction_covariance(pcam, std_dev_angle, out_file): 1449 batch.init_process("vpglComputePerspCamPACovarianceProcess") 1450 batch.set_input_from_db(0, pcam) 1451 batch.set_input_float(1, std_dev_angle) 1452 batch.set_input_string(2, out_file) 1453 batch.run_process() 1454 1455# uniformly sample a camera rotated around principle axis 1456 1457 1458def perturb_camera_uniform(cam_in, angle, rng): 1459 batch.init_process('vpglPerturbUniformPerspCamOrientProcess') 1460 batch.set_input_from_db(0, cam_in) 1461 batch.set_input_float(1, angle) 1462 batch.set_input_from_db(2, rng) 1463 batch.run_process() 1464 (id, type) = batch.commit_output(0) 1465 pert_cam = dbvalue(id, type) 1466 (theta_id, type) = batch.commit_output(1) 1467 (phi_id, type) = batch.commit_output(2) 1468 theta = batch.get_output_float(theta_id) 1469 phi = batch.get_output_float(phi_id) 1470 return pert_cam, theta, phi 1471 1472 1473def create_perspective_camera_with_motion_dir(pcam, cent_x, cent_y, cent_z, cent2_x, cent2_y, cent2_z): 1474 batch.init_process("vpglCreatePerspectiveCameraProcess4") 1475 batch.set_input_from_db(0, pcam) 1476 batch.set_input_float(1, cent_x) 1477 batch.set_input_float(2, cent_y) 1478 batch.set_input_float(3, cent_z) 1479 batch.set_input_float(4, cent2_x) 1480 batch.set_input_float(5, cent2_y) 1481 batch.set_input_float(6, cent2_z) 1482 batch.run_process() 1483 (c_id, c_type) = batch.commit_output(0) 1484 cam = dbvalue(c_id, c_type) 1485 return cam 1486 1487 1488def pers_cam_from_photo_overlay(lvcs, heading, tilt, roll, lat, lon, alt, fov_hor, fov_ver, ni, nj): 1489 batch.init_process("vpglPerspCameraFromPhotoOverlayProcess") 1490 batch.set_input_from_db(0, lvcs) 1491 batch.set_input_float(1, heading) 1492 batch.set_input_float(2, tilt) 1493 batch.set_input_float(3, roll) 1494 batch.set_input_float(4, lat) 1495 batch.set_input_float(5, lon) 1496 batch.set_input_float(6, alt) 1497 batch.set_input_float(7, fov_hor) 1498 batch.set_input_float(8, fov_ver) 1499 batch.set_input_unsigned(9, ni) 1500 batch.set_input_unsigned(10, nj) 1501 batch.run_process() 1502 (c_id, c_type) = batch.commit_output(0) 1503 cam = dbvalue(c_id, c_type) 1504 return cam 1505 1506 1507def create_perspective_camera_krt(k, r, t): 1508 ''' Take a k(3x3), r(3x3), and t(3) numpy array and returns a database object 1509 1510 k, r, t can also be a flattened list 1511 ''' 1512 if type(k) != list: 1513 k = k.flatten().tolist() 1514 if type(r) != list: 1515 r = r.flatten().tolist() 1516 if type(t) != list: 1517 t = t.flatten().tolist() 1518 1519 batch.init_process("vpglCreatePerspectiveCameraProcess5") 1520 batch.set_input_double_array(0, k) 1521 batch.set_input_double_array(1, r) 1522 batch.set_input_double_array(2, t) 1523 batch.run_process() 1524 (db_id, db_type) = batch.commit_output(0) 1525 cam = dbvalue(db_id, db_type) 1526 return cam 1527 1528 1529# input two sets of points that correspond to each other in two different coordinate systems 1530# compute the similarity transformation that maps space of pts0 to space of pts1, the size of pts0 and pts1 better match! 1531# outputs a 4 by 4 similarity matrix as a vector of size 16 1532# construct the matrix as follows 1533# 0 1 2 3 1534# 4 5 6 7 1535# 8 9 10 11 1536# 12 13 14 15 1537def compute_transformation(pts0_xs, pts0_ys, pts0_zs, 1538 pts1_xs, pts1_ys, pts1_zs, 1539 input_cam_folder, output_cam_folder): 1540 batch.init_process("vpglTransformSpaceProcess") 1541 batch.set_input_double_array(0, pts0_xs) 1542 batch.set_input_double_array(1, pts0_ys) 1543 batch.set_input_double_array(2, pts0_zs) 1544 batch.set_input_double_array(3, pts1_xs) 1545 batch.set_input_double_array(4, pts1_ys) 1546 batch.set_input_double_array(5, pts1_zs) 1547 batch.set_input_string(6, input_cam_folder) 1548 batch.set_input_string(7, output_cam_folder) 1549 batch.run_process() 1550 (id, type) = batch.commit_output(0) 1551 matrix_as_array = batch.get_output_double_array(id) 1552 batch.remove_data(id) 1553 (id, type) = batch.commit_output(1) 1554 scale = batch.get_output_double(id) 1555 batch.remove_data(id) 1556 return matrix_as_array, scale 1557 1558# inputs a 4 by 4 similarity matrix as a vector of size 16 1559# construct the matrix as follows 1560# 0 1 2 3 1561# 4 5 6 7 1562# 8 9 10 11 1563# 12 13 14 15 1564def compute_transformed_box(min_pt, max_pt, matrix_as_array): 1565 batch.init_process("vpglTransformBoxProcess") 1566 batch.set_input_double_array(0, min_pt) 1567 batch.set_input_double_array(1, max_pt) 1568 batch.set_input_double_array(2, matrix_as_array) 1569 batch.run_process() 1570 (id, type) = batch.commit_output(0) 1571 out_min_pt = batch.get_output_double_array(id) 1572 batch.remove_data(id) 1573 (id, type) = batch.commit_output(1) 1574 out_max_pt = batch.get_output_double_array(id) 1575 batch.remove_data(id) 1576 return out_min_pt, out_max_pt 1577 1578# get connected component of a geotiff image 1579def find_connected_component(in_img, in_cam, threshold, out_kml, is_above=True): 1580 batch.init_process("vpglFindConnectedComponentProcess") 1581 batch.set_input_from_db(0, in_img) 1582 batch.set_input_from_db(1, in_cam) 1583 batch.set_input_float(2, threshold) 1584 batch.set_input_string(3, out_kml) 1585 batch.set_input_bool(4, is_above) 1586 status = batch.run_process() 1587 if status: 1588 (id, type) = batch.commit_output(0) 1589 out_img = dbvalue(id, type) 1590 (id, type) = batch.commit_output(1) 1591 num_regions = batch.get_output_unsigned(id) 1592 return out_img, num_regions 1593 else: 1594 raise VpglException("Failed to find connected components") 1595 1596# rotate a image north up based on its RPC camera. The return value is 1597# rotation angle between -Pi to Pi 1598def rational_camera_rotate_to_north(in_cam): 1599 batch.init_process("vpglRationalCamRotationToNorthProcess") 1600 batch.set_input_from_db(0, in_cam) 1601 status = batch.run_process() 1602 if status: 1603 (id, type) = batch.commit_output(0) 1604 ang_in_deg = batch.get_output_double(id) 1605 return ang_in_deg 1606 else: 1607 raise VpglException("Failed to get north angle from rational camera") 1608 1609# rotate a image north up based on its RPC camera. The return value is 1610# rotation angle between -Pi to Pi 1611def rational_camera_get_up_vector(in_cam): 1612 batch.init_process("vpglRationalCamRotationToUpVectorProcess") 1613 batch.set_input_from_db(0, in_cam) 1614 status = batch.run_process() 1615 if status: 1616 (id, type) = batch.commit_output(0) 1617 u = batch.get_output_double(id) 1618 (id, type) = batch.commit_output(1) 1619 v = batch.get_output_double(id) 1620 return u,v 1621 else: 1622 raise VpglException("Failed to get north angle from rational camera") 1623 1624# create a DEM manager to support DEM utility functions 1625# note if zmin > zmax, these values will be calculated from the DEM 1626def create_DEM_manager(dem_img_resc,zmin=0.0,zmax=-1.0): 1627 batch.init_process("vpglCreateDemManagerProcess") 1628 batch.set_input_from_db(0, dem_img_resc) 1629 batch.set_input_double(1, zmin) 1630 batch.set_input_double(2, zmax) 1631 status = batch.run_process() 1632 if status: 1633 (id0, type) = batch.commit_output(0) 1634 dem_mgr = dbvalue(id0, type) 1635 (id1, type) = batch.commit_output(1) 1636 zmin = batch.get_output_double(id1) 1637 (id2, type) = batch.commit_output(2) 1638 zmax = batch.get_output_double(id2) 1639 return (dem_mgr,zmin,zmax) 1640 raise VpglException("failed to create a DEM manager") 1641 1642# Backproject an image point onto the DEM and return a 3-d point 1643def DEM_backproj(dem_mgr, cam, u, v, err_tol = 1.0): 1644 batch.init_process("vpglBackprojectDemProcess") 1645 batch.set_input_from_db(0, dem_mgr) 1646 batch.set_input_from_db(1, cam) 1647 batch.set_input_double(2, u) 1648 batch.set_input_double(3, v) 1649 batch.set_input_double(4, err_tol) 1650 status = batch.run_process() 1651 if status: 1652 (id0, type) = batch.commit_output(0) 1653 x = batch.get_output_double(id0) 1654 (id1, type) = batch.commit_output(1) 1655 y = batch.get_output_double(id1) 1656 (id2, type) = batch.commit_output(2) 1657 z = batch.get_output_double(id2) 1658 batch.remove_data(id0) 1659 batch.remove_data(id1) 1660 batch.remove_data(id2) 1661 return (x, y, z) 1662 raise VpglException("failed to backproject onto the DEM") 1663 1664# convert a geotiff image to a ASCII xyz point cloud file via a LVCS conversion 1665def dem_to_pts_lvcs(img, cam, lvcs, out_file, is_convert_z = True): 1666 batch.init_process("vpglConvertGeotiffToPointCloudProcess") 1667 batch.set_input_from_db(0, img) 1668 batch.set_input_from_db(1, cam) 1669 batch.set_input_from_db(2, lvcs) 1670 batch.set_input_string(3, out_file) 1671 batch.set_input_bool(4, is_convert_z) 1672 status = batch.run_process() 1673 if status: 1674 (id, type) = batch.commit_output(0) 1675 n_pts = batch.get_output_unsigned(id) 1676 return n_pts 1677 raise VpglException("failed to convert geotiff to point clouds") 1678 1679# Project a reference image that controled by a rational camera onto target image domain using DEM 1680def DEM_project_img(dem_mgr, ref_img, ref_cam, tgr_cam, tgr_i0, tgr_j0, tgr_ni, tgr_nj, err_tol = 1.0): 1681 batch.init_process("vpglDemImageProjectionProcess") 1682 batch.set_input_from_db(0, ref_img) 1683 batch.set_input_from_db(1, ref_cam) 1684 batch.set_input_from_db(2, dem_mgr) 1685 batch.set_input_from_db(3, tgr_cam) 1686 batch.set_input_unsigned(4, tgr_i0) 1687 batch.set_input_unsigned(5, tgr_j0) 1688 batch.set_input_unsigned(6, tgr_ni) 1689 batch.set_input_unsigned(7, tgr_nj) 1690 batch.set_input_double(8, err_tol) 1691 status = batch.run_process() 1692 if status: 1693 (id0, type0) = batch.commit_output(0) 1694 out_img = dbvalue(id0, type0) 1695 (id1, type1) = batch.commit_output(1) 1696 err_cnt = batch.get_output_unsigned(id1) 1697 return out_img, err_cnt 1698 raise VpglException("failed to project reference image to target image using DEM manager") 1699