a `e[@sddlZddlZddlZddlZddlmZddlZddlmZddl m Z ddl m Z ddl mZddlmZddlmZmZd d Zd d Zd3ddZd4ddZddZddZddZd5ddZddZd6d!d"Zd7d%d&Zd8d(d)Zd*d+Z d,d-Z!d9d/d0Z"d1d2Z#dS):N)dls)log) parallel_map)imread)exposure)disk)rankgaussiancCs|d}t|jdkr*tdt|j|r6|S|\}}}|}|j}|}|j }| } |dur| durt d|j |S|dur| dur| }t|\} } } | durtt|jt|j\} } |dur||8}|} | r|| }nt d|j | durHtj| ddddtjf|jddd} || 9}|r|dur|durd d || ||| }tj|ddddtjf|jddd}||9}|durd ||d k<|dur|dur|||}||9}|dur||9}|S) z Convert Digital Number values to Radiance values :param photo ODM_Photo :param image numpy array containing image data :return numpy array with radiance image values float32z-Image should have shape length of 3 (got: %s)NzCannot perform radiometric calibration, no FNumber/Exposure Time or Radiometric Calibration EXIF tags found in %s. Using Digital Number.z0Cannot normalize DN for %s, bit depth is missing)axis?r)astypelenshape ValueError is_thermalget_radiometric_calibrationget_dark_level exposure_timeget_gaingain_adjustmentget_photometric_exposurer ODM_WARNINGfilename vignette_mapnpmeshgridarangewidthheightget_bit_depth_maxrepeatnewaxis)photoimagea1a2a3Z dark_levelrgainrZphotometric_expVxyZ bit_depth_maxRr//code/opendm/multispectral.pydn_to_radiancesP    **    r1c Cs|\}}|}|r|r|dt|}tt|jt|j\}}t ||||}t ||}|j dkrd|}|||fSdS)NrDJI)NNN) get_vignetting_centerget_vignetting_polynomialappendrarrayrrr r!hypotpolyval camera_make) r%Zx_vcZy_vc polynomialZ vignette_polyr,r-rZvignetter/r/r0r[s       rTcCs$t||}t||d}|tj|S)N)use_sun_sensor)r1compute_irradiancemathpi)r%r&r<ZradianceZ irradiancer/r/r0dn_to_reflectance{s  r@cCs|r dS|}|dur |S|r|rtgd}t|j|jg| | |\}}}}}t |} d} |} d| } | | } | | t |}|}|| }|t ||}|S|rtd|jdS)Nr)rrg@z!No sun sensor values found for %s)rget_horizontal_irradianceget_sun_sensorrr6rZcompute_sun_anglelatitude longitude get_dls_pose get_utc_timeZfresnelcossinrrr)r%r<Z hirradianceZdls_orientation_vectorZsun_vector_nedZsensor_vector_nedZsun_sensor_angleZsolar_elevationZ solar_azimuthZangular_correctionZdirect_to_diffuse_ratiospectral_irradianceZpercent_diffuseZsensor_irradianceZuntilted_direct_irrZdirect_irradianceZscattered_irradiancehorizontal_irradiancer/r/r0r=s6  r=cCs0t||}|D]}|d|kr|dSqdS)Nnamephotos)get_primary_band_name) multi_camerauser_band_name band_namebandr/r/r0get_photos_by_bands  rScCst|dkrtd|dkrnddgddgdd gfD].}|D]$}|d |vr:|d Sq:q2|d d S|D]$}|d |krr|d Sqr|d d }td ||f|S) NzInvalid multi_camera listautorgb redgreenbluegreengbluebrLrz1Cannot find band name "%s", will use "%s" instead)r Exceptionlowerrr)rOrPaliasesrRZband_name_fallbackr/r/r0rNs   rNc Cs(t||}d}|D]}|d|kr|d}q0qzi}i}i}|D]@}|} | durdtd|j|| durztd||| <qB|D]|}|d} | D]j}|} | durtd|j|| durtd|| ||j<|d|kr||| jg|qq||fWSty"} ztdt | i} i}i}t d } |D]8}t | d |j}||jkr|td |j|| |<qN|D]x}|d} | D]d}t | d |j}||jkrtd |j| |||j<|d|kr|| |jg|qq||fWYd} ~ Sd} ~ 00dS) z Computes maps of: - { photo filename --> associated primary band photo } (s2p) - { primary band filename --> list of associated secondary band photos } (p2s) by looking at capture UUID, capture time or filenames as a fallback NrLrMz.Cannot use capture time (no information in %s)z1Unreliable UUID/capture time detected (duplicate)z3Cannot use UUID/capture time (no information in %s)z=Unreliable UUID/capture time detected (no primary band match)z%s, will use filenames insteadz^(.+)[-_]\w+(\.[A-Za-z]{3,4})$z\1\2zcCannot match bands by filename on %s, make sure to name your files [filename]_band[.ext] uniformly.) rNget_capture_idr\rget setdefaultr5rrstrrecompilesub)rO primary_bandrQZprimary_band_photosrRZ unique_id_maps2pp2spuuidrMeZ filename_mapZ file_regexZfilename_without_bandr/r/r0compute_band_mapssd          rlrTcstdi}|D]}|d|krgfdd} t| dd|dD|dd D]D} tgd } | d } D]} | t| | d 7} qx| | d <qZjd dddtdkrd||d<td|ddddd fqt d|dq|S)NzComputing band alignmentrLc s ztkrWdS|d}|durBtd|dWdSttj|dtj|j\}}}|durt d|d|jf |t j |||dnt d|d|jfWn@ty}z&td|dt|fWYd}~n d}~00dS)Nrz%Cannot find primary band photo for %sz%s --> %s good match) warp_matrixeigvals dimensionalgoz%s --> %s cannot be matchedz'Failed to compute homography for %s: %s)rr`rrcompute_homographyospathjoinrODM_INFOr5rlinalgror\rb)riZprimary_band_photornrprqrk images_pathZmatrices max_samplesrgr/r0parallel_compute_homography)s*    z?compute_alignment_matrices..parallel_compute_homographycSsg|]}d|jiqSrr|).0rir/r/r0 Gz.compute_alignment_matrices..rMF)Zsingle_thread_fallback)rrroscorecSs|dS)Nrr/)r,r/r/r0Urz,compute_alignment_matrices..)keyreverserz8%s band will be aligned using warp matrix %s (score: %s)rnzKCannot find alignment matrix for band %s, The band might end up misaligned!) rrvrrr6abssumsortrr)rOZprimary_band_nameryrgrhmax_concurrencyrzZalignment_inforRr{m1accrkm2r/rxr0compute_alignment_matricess&   *rc szht|ddd}|jddkr4tt|tjnt|dddddftj}|dkr~tdjdjdft|ddd}|jddkrtt|tjnt|dddddffd d }d}d}d}|dkr0d }|t } | ddurXd }t d |t } | ddurXd}n(d }t d|t } | ddurXd}| \}}|||fWSt y} z tdt | WYd} ~ dSd} ~ 00dS)NT) unchangedanydepthr r ri@zGSmall image for band alignment (%sx%s), this might be tough to compute.rTc sz|}Wn8tyF}z tdt|WYd}~dSd}~00|durTdStj|}t|dkrpdStjj|dd}|ddkrdS|d|d}|dkrdS|j d j dffS) NzCannot compute homography: %s)NNNg?F) compute_uvrArirT) r\rrrbrrwdetrsvdr) algorithmhrkrrratioalign_image_gray image_grayr/r0 compute_usingrs"   z)compute_homography..compute_usingZfeatZecczACan't use features matching, will use ECC (this might take a bit)z!Using ECC (this might take a bit)zCompute homography: %s)NrN)rrto_8bitcv2cvtColorCOLOR_BGR2GRAYmaxrrfind_features_homographyrvfind_ecc_homographyr\rb) Zimage_filenameZalign_image_filenamer&max_dim align_imagerrnrprqresultrkr/rr0rr_sF     rr:0yE>-C6?c Cs>d}|j\}}t||}d} || kr^||kr6| |} n| |} tj|d| | tjd}|j\}}t||} | dkr| d} |d7}qhtd||jd|jdkrt|}t|}|jd|jd} |jd|jd} tj|d| | | dkr| dkrtjntj d}|g}|g}t |D]r}t|dd d |d<| dtj|ddd d tjdt|dd d |d<| dtj|ddd d tjdq"t j d d t jd }|t jgdgdgdgt jd d|d}t |dD]P}tt||}tt||}||kr&|dkr&|}n|||||}tjtjB||f}z0td|tj|||tj|ddd\}}Wnty}zn||krtd|t j d d t jd }|t jgdgdgdgt jd d|d}n|WYd}~n d}~00||kr|t jgdgdgdgt jd }q|S)Nrifxfy interpolationi,g@rTzPyramid levels: %srT)force_normalize?r dtype)rTrTr )rrrTzComputing ECC pyramid level %s )Z inputMaskZ gaussFiltSizezGCould not compute ECC warp_matrix at pyramid level %s, resetting matrix)rrrresize INTER_AREAminrrvrINTER_LANCZOS4rangeinsertreyer r6gradientr TERM_CRITERIA_EPSTERM_CRITERIA_COUNTfindTransformECCMOTION_HOMOGRAPHYr\)rrZnumber_of_iterationsZtermination_epsZ start_epsZpyramid_levelsrwrmax_sizefmin_dimrrZimage_gray_pyrZalign_image_pyrlevelrnZigZaigepsZcriteria_rkr/r/r0rsv        2 " 4 *rffffff? c Cs&tjddd}|j\}}t||}d}||krh||kr@||} n||} tj|d| | tjd}|j\}}|jd|jdkr|jd|jd} |jd|jd} tj|d| | | dkr| dkrtjntjd}||d\} } ||d\}}d}t|d d }td d }t ||}z|j | |d d}Wn(t yR}zWYd}~dSd}~00g}|D]&\}}|j ||j kr\| |q\|}t||krdStjt|d ftjd}tjt|d ftjd}t|D]:\}}| |jj||ddf<||jj||ddf<qt||tj\}}|S)Nrg?) edgeThresholdcontrastThresholdirrrTr)rZtrees2)Zchecksr )kr)r SIFT_createrrrrrdetectAndComputedictFlannBasedMatcherknnMatchr\distancer5rrzerosr enumeratequeryIdxpttrainIdxfindHomographyRANSAC)rrZfeature_retentionZmin_match_countdetectorrrrrrrrZkp_imageZ desc_imageZkp_align_imageZdesc_align_imageFLANN_INDEX_KDTREEZ index_paramsZ search_paramsflannmatchesrkZ good_matchesmnZ points_imageZpoints_align_imageimatchrr/r/r0rsT        rrcCsVt|}tj|tjdd|d}tj|tjdd|d}tt|dt|dd}|S)NrTr)ksizer)local_normalizerSobelCV_32F addWeightedrabsolute)imrZgrad_xZgrad_yZgradr/r/r0r?s rcCsD|j\}}t|d}|ddkr*|d}t|}tj||d}|S)Nrr rrT)selem)rintrrZequalize)rr rZdisksizerr/r/r0rFs   rcCs4t||}|jdkr"t|||St|||SdS)N)r r ) resize_matchrrwarpPerspective warpAffine)r&rnrpr/r/r0rPs  rFcCs|s|jtjkr|Sz(t|j}d}t|jt|j}Wn.tyjt|}t||}Yn0|tj }||8}|d|9}tj ||dd||dk<d||dk<|tj}|S)Nrgo@)out) rruint8iinfofloatrrrrr around)r&rZ data_range min_value value_ranger/r/r0rYs"        rcCsn|jd|jd}}|\}}||ks.||krj||}||}tj|d|||dkr`|dkr`tjntjd}|S)NrrTrr)rrrrr)r&rprrmwZmhrrr/r/r0rrsr)T)T)rTrm)rrr)rr)r)F)$r>rcrrsopendmrnumpyrrZopendm.concurrencyrZ opensfm.iorZskimagerZskimage.morphologyrZskimage.filtersrr r1rr@r=rSrNrlrrrrrrrrrrr/r/r/r0s6      J  ,T @K R C