def _get_ang_scale(ims, bgval, exponent='inf', constraints=None, reports=None): """ Given two images, return their scale and angle difference. Args: ims (2-tuple-like of 2D ndarrays): The images bgval: We also pad here in the :func:`map_coordinates` exponent (float or 'inf'): The exponent stuff, see :func:`similarity` constraints (dict, optional) reports (optional) Returns: tuple: Scale, angle. Describes the relationship of the subject image to the first one. """ assert len(ims) == 2, \ "Only two images are supported as input" shape = ims[0].shape ims_apod = [utils._apodize(im) for im in ims] dfts = [ fft.fftshift( fft.fft2(im, threads=4, overwrite_input=True, auto_align_input=True, auto_contiguous=True, planner_effort='FFTW_ESTIMATE')) for im in ims_apod ] filt = _logpolar_filter(shape) dfts = [dft * filt for dft in dfts] # High-pass filtering used to be here, but we have moved it to a higher # level interface pcorr_shape = _get_pcorr_shape(shape) log_base = _get_log_base(shape, pcorr_shape[1]) stuffs = [_logpolar(np.abs(dft), pcorr_shape, log_base) for dft in dfts] (arg_ang, arg_rad), success = _phase_correlation(stuffs[0], stuffs[1], utils.argmax_angscale, log_base, exponent, constraints, reports) angle = -np.pi * arg_ang / float(pcorr_shape[0]) angle = np.rad2deg(angle) angle = utils.wrap_angle(angle, 360) scale = log_base**arg_rad angle = -angle scale = 1.0 / scale if not 0.5 < scale < 2: raise ValueError( "Images are not compatible. Scale change %g too big to be true." % scale) return scale, angle
def _get_ang_scale(ims, bgval, exponent='inf', constraints=None, reports=None): """ Given two images, return their scale and angle difference. Args: ims (2-tuple-like of 2D ndarrays): The images bgval: We also pad here in the :func:`map_coordinates` exponent (float or 'inf'): The exponent stuff, see :func:`similarity` constraints (dict, optional) reports (optional) Returns: tuple: Scale, angle. Describes the relationship of the subject image to the first one. """ assert len(ims) == 2, \ "Only two images are supported as input" shape = ims[0].shape ims_apod = [utils._apodize(im) for im in ims] dfts = [fft.fftshift(fft.fft2(im)) for im in ims_apod] filt = _logpolar_filter(shape) dfts = [dft * filt for dft in dfts] # High-pass filtering used to be here, but we have moved it to a higher # level interface pcorr_shape = _get_pcorr_shape(shape) log_base = _get_log_base(shape, pcorr_shape[1]) stuffs = [_logpolar(np.abs(dft), pcorr_shape, log_base) for dft in dfts] (arg_ang, arg_rad), success = _phase_correlation(stuffs[0], stuffs[1], utils.argmax_angscale, log_base, exponent, constraints, reports) angle = -np.pi * arg_ang / float(pcorr_shape[0]) angle = np.rad2deg(angle) angle = utils.wrap_angle(angle, 360) scale = log_base**arg_rad angle = -angle scale = 1.0 / scale if reports is not None: reports["shape"] = filt.shape reports["base"] = log_base if reports.show("spectra"): reports["dfts_filt"] = dfts if reports.show("inputs"): reports["ims_filt"] = [ fft.ifft2(np.fft.ifftshift(dft)) for dft in dfts ] if reports.show("logpolar"): reports["logpolars"] = stuffs if reports.show("scale_angle"): reports["amas-result-raw"] = (arg_ang, arg_rad) reports["amas-result"] = (scale, angle) reports["amas-success"] = success extent_el = pcorr_shape[1] / 2.0 reports["amas-extent"] = (log_base**(-extent_el), log_base**extent_el, -90, 90) if not 0.5 < scale < 2: raise ValueError( "Images are not compatible. Scale change %g too big to be true." % scale) return scale, angle
def _get_ang_scale(ims, bgval, exponent='inf', constraints=None, reports=None): """ Given two images, return their scale and angle difference. Args: ims (2-tuple-like of 2D ndarrays): The images bgval: We also pad here in the :func:`map_coordinates` exponent (float or 'inf'): The exponent stuff, see :func:`similarity` constraints (dict, optional) reports (optional) Returns: tuple: Scale, angle. Describes the relationship of the subject image to the first one. """ assert len(ims) == 2, \ "Only two images are supported as input" shape = ims[0].shape ims_apod = [utils._apodize(im) for im in ims] dfts = [fft.fftshift(fft.fft2(im)) for im in ims_apod] filt = _logpolar_filter(shape) dfts = [dft * filt for dft in dfts] # High-pass filtering used to be here, but we have moved it to a higher # level interface pcorr_shape = _get_pcorr_shape(shape) log_base = _get_log_base(shape, pcorr_shape[1]) stuffs = [_logpolar(np.abs(dft), pcorr_shape, log_base) for dft in dfts] (arg_ang, arg_rad), success = _phase_correlation( stuffs[0], stuffs[1], utils.argmax_angscale, log_base, exponent, constraints, reports) angle = -np.pi * arg_ang / float(pcorr_shape[0]) angle = np.rad2deg(angle) angle = utils.wrap_angle(angle, 360) scale = log_base ** arg_rad angle = - angle scale = 1.0 / scale if reports is not None: reports["shape"] = filt.shape reports["base"] = log_base if reports.show("spectra"): reports["dfts_filt"] = dfts if reports.show("inputs"): reports["ims_filt"] = [fft.ifft2(np.fft.ifftshift(dft)) for dft in dfts] if reports.show("logpolar"): reports["logpolars"] = stuffs if reports.show("scale_angle"): reports["amas-result-raw"] = (arg_ang, arg_rad) reports["amas-result"] = (scale, angle) reports["amas-success"] = success extent_el = pcorr_shape[1] / 2.0 reports["amas-extent"] = ( log_base ** (-extent_el), log_base ** extent_el, -90, 90 ) if not 0.5 < scale < 2: raise ValueError( "Images are not compatible. Scale change %g too big to be true." % scale) return scale, angle