def align_strong(I, Iref, scales=(0.15, 0.2, 0.25, 0.3), crop_I=(0.05, 0.05, 0.05, 0.05), crop_Iref=None, do_nan_to_num=False): """ Alignment strategy: First, crop out 5% from each side of I. Then, try a range of scales, and choose the alignment that minimizes the error. CURRENTLY NOT USED. """ if crop_I != None: Icrop = cropout_stuff(I, crop_I[0], crop_I[1], crop_I[2], crop_I[3]) else: Icrop = I if crop_Iref != None: Iref_crop = cropout_stuff(Iref, crop_Iref[0], crop_Iref[1], crop_Iref[2], crop_Iref[3]) else: Iref_crop = Iref H_best, Ireg_best, err_best = None, None, None scale_best = None for scale in scales: H, Ireg, err = imagesAlign.imagesAlign(Icrop, Iref_crop, fillval=1, trfm_type='rigid', rszFac=scale) if err_best == None or err < err_best: H_best = H Ireg_best = Ireg err_best = err scale_best = scale # Finally, apply H_BEST to I Ireg = sh.imtransform(I, H_best) if do_nan_to_num: Ireg = np.nan_to_num(Ireg) return H_best, Ireg, err_best
def align_image(I, Iref, crop=True, verbose=False, CROPX=0.02, CROPY=0.02, ERR_REL_THR=1.001, RSZFAC=0.15, MINAREA=None): """ Aligns I to IREF (e.g. 'global' alignment). Both IREF and I must be correctly 'flipped' before you pass it to this function. Input: nparray IREF The reference image that we are aligning against. nparray I The image that we want to align. float CROPX, CROPY, OR tuple CROPX, tuple CROPY The amount to crop off the top+bottom and left+right of the image (used with CROP=True). If CROPX, CROPY are tuples, they must be the same length, and we will try all sequential pairs until we get a relative error that is <= ERR_REL_THR. If none are <= ERR_REL_THR, then we output the alignment with smallest error. float ERR_REL_THR See the docstring for the tuple-version of CROPX, CROPY. int MINAREA This parameter dictates how "far down" the pyramid optimization should downscale the image. For instance, if MINAREA is K, then a new pyramid level will be created by downscaling the image by a factor of 2.0 until the image area is <= K. Larger values of MINAREA mean that alignment is done at larger scales, which will lead to better accuracy, but may take more time. Smaller values of MINAREA incur better speedsup, but potentially at the cost of accuracy. The default value 2**16 is a reasonable value for accuracy. Output: (nparray H, nparray IREG, float err) where H is the transformation matrix, IREG is the result of aligning I to IREF, and ERR is the alignment error (a float from [0.0, 1.0]). """ if MINAREA is None: MINAREA = np.power(2, 16) if crop and type(CROPX) in (list, tuple): return _align_image_mult(I, Iref, CROPX, CROPY, ERR_REL_THR) if crop == True: Iref_crop = cropout_stuff(Iref, CROPY, CROPY, CROPX, CROPX) Icrop = cropout_stuff(I, CROPY, CROPY, CROPX, CROPX) else: Icrop, Iref_crop = I, Iref H, err = imagesAlign.imagesAlign(Icrop, Iref_crop, trfm_type='rigid', rszFac=RSZFAC, applyWarp=False, minArea=MINAREA) if verbose: print "Alignment Err: ", err Ireg = sh.imtransform(I, H) # Ireg = np.nan_to_num(Ireg) return H, Ireg, err
def align(groupid, dat): res = [] translations = [] for i, group in enumerate(zip(*dat)): if i == 0: # We want to look at everything for the title left_border = 0 else: # Skip the voting target for the rest #left_border = 80 left_border = 0 Iref_orig = sh.standardImread(group[0], flatten=True) Iref = Iref_orig[:, left_border:] r = [] r_img = [] for i in range(len(group)): I_orig = sh.standardImread(group[i], flatten=True) I = I_orig[:, left_border:] Inorm = make_norm(I, Iref) (H, imres, err) = imagesAlign.imagesAlign(Inorm, Iref, trfm_type='translation') r_img.append((make_norm(I_orig, Iref_orig), H)) r.append(translate(group[i])) translations.append(r_img) res.append(r) translated_images = [] for contest in zip(*translations): c_res = [] """ print 'new' arr = np.zeros((3,3)) for _,H in contest: arr += H arr /= len(contest) print arr """ for img, H in contest: translated = sh.imtransform(np.copy(img), H, fillval=np.nan) align_res = np.nan_to_num(translated) c_res.append(align_res) translated_images.append(c_res) translated_images = zip(*translated_images) return res, translated_images
def align(groupid, dat): res = [] translations = [] for i,group in enumerate(zip(*dat)): if i == 0: # We want to look at everything for the title left_border = 0 else: # Skip the voting target for the rest #left_border = 80 left_border = 0 Iref_orig=sh.standardImread(group[0],flatten=True) Iref = Iref_orig[:,left_border:] r = [] r_img = [] for i in range(len(group)): I_orig=sh.standardImread(group[i],flatten=True) I=I_orig[:,left_border:] Inorm = make_norm(I, Iref) (H,imres,err)=imagesAlign.imagesAlign(Inorm,Iref,trfm_type='translation') r_img.append((make_norm(I_orig, Iref_orig), H)) r.append(translate(group[i])) translations.append(r_img) res.append(r) translated_images = [] for contest in zip(*translations): c_res = [] """ print 'new' arr = np.zeros((3,3)) for _,H in contest: arr += H arr /= len(contest) print arr """ for img,H in contest: translated = sh.imtransform(np.copy(img), H, fillval=np.nan) align_res = np.nan_to_num(translated) c_res.append(align_res) translated_images.append(c_res) translated_images = zip(*translated_images) return res, translated_images
def align_image(I, Iref, crop=True, verbose=False, CROPX=0.02, CROPY=0.02, ERR_REL_THR=1.001, RSZFAC=0.15, MINAREA=None): """ Aligns I to IREF (e.g. 'global' alignment). Both IREF and I must be correctly 'flipped' before you pass it to this function. Input: nparray IREF The reference image that we are aligning against. nparray I The image that we want to align. float CROPX, CROPY, OR tuple CROPX, tuple CROPY The amount to crop off the top+bottom and left+right of the image (used with CROP=True). If CROPX, CROPY are tuples, they must be the same length, and we will try all sequential pairs until we get a relative error that is <= ERR_REL_THR. If none are <= ERR_REL_THR, then we output the alignment with smallest error. float ERR_REL_THR See the docstring for the tuple-version of CROPX, CROPY. int MINAREA This parameter dictates how "far down" the pyramid optimization should downscale the image. For instance, if MINAREA is K, then a new pyramid level will be created by downscaling the image by a factor of 2.0 until the image area is <= K. Larger values of MINAREA mean that alignment is done at larger scales, which will lead to better accuracy, but may take more time. Smaller values of MINAREA incur better speedsup, but potentially at the cost of accuracy. The default value 2**16 is a reasonable value for accuracy. Output: (nparray H, nparray IREG, float err) where H is the transformation matrix, IREG is the result of aligning I to IREF, and ERR is the alignment error (a float from [0.0, 1.0]). """ if MINAREA == None: MINAREA = np.power(2, 16) if crop and type(CROPX) in (list, tuple): return _align_image_mult(I, Iref, CROPX, CROPY, ERR_REL_THR) if crop == True: Iref_crop = cropout_stuff(Iref, CROPY, CROPY, CROPX, CROPX) Icrop = cropout_stuff(I, CROPY, CROPY, CROPX, CROPX) else: Icrop, Iref_crop = I, Iref H, err = imagesAlign.imagesAlign(Icrop, Iref_crop, trfm_type='rigid', rszFac=RSZFAC, applyWarp=False, minArea=MINAREA) if verbose: print "Alignment Err: ", err Ireg = sh.imtransform(I, H) #Ireg = np.nan_to_num(Ireg) return H, Ireg, err
def _align_image_mult(I, Iref, CROPX, CROPY, ERR_REL_THR): """ Helper function for align_image. Handles trying multiple crop parameters until an err_rel is found that is <= ERR_REL_THR. """ best_H, best_Ireg, best_err = None, None, None err_orig = np.mean(np.abs(I - Iref).flatten()) # L1 error, normalized by area for i, cropx in enumerate(CROPX): cropy = CROPY[i] I_crop = cropout_stuff(I, cropy, cropy, cropx, cropx) Iref_crop = cropout_stuff(Iref, cropy, cropy, cropx, cropx) H, err = imagesAlign.imagesAlign(I_crop, Iref_crop, trfm_type='rigid', rszFac=0.15, applyWarp=False) Ireg = sh.imtransform(I, H) err_galign = np.mean(np.abs(Ireg - Iref).flatten()) err_rel = err_galign / err_orig if err_orig != 0.0 else 0.0 if err_rel <= ERR_REL_THR: return H, Ireg, err_galign elif best_H == None or err_galign < best_err: best_H, best_Ireg, best_err = H, Ireg, err_galign return best_H, best_Ireg, best_err
def align_strong(I, Iref, scales=(0.15, 0.2, 0.25, 0.3), crop_I=(0.05, 0.05, 0.05, 0.05), crop_Iref=None, do_nan_to_num=False): """ Alignment strategy: First, crop out 5% from each side of I. Then, try a range of scales, and choose the alignment that minimizes the error. CURRENTLY NOT USED. """ if crop_I != None: Icrop = cropout_stuff(I, crop_I[0], crop_I[1], crop_I[2], crop_I[3]) else: Icrop = I if crop_Iref != None: Iref_crop = cropout_stuff(Iref, crop_Iref[0], crop_Iref[1], crop_Iref[2], crop_Iref[3]) else: Iref_crop = Iref H_best, Ireg_best, err_best = None, None, None scale_best = None for scale in scales: H, Ireg, err = imagesAlign.imagesAlign(Icrop, Iref_crop, fillval=1, trfm_type='rigid', rszFac=scale) if err_best == None or err < err_best: H_best = H Ireg_best = Ireg err_best = err scale_best = scale # Finally, apply H_BEST to I Ireg = sh.imtransform(I, H_best) if do_nan_to_num: Ireg = np.nan_to_num(Ireg) return H_best, Ireg, err_best
def _align_image_mult(I, Iref, CROPX, CROPY, ERR_REL_THR): """ Helper function for align_image. Handles trying multiple crop parameters until an err_rel is found that is <= ERR_REL_THR. """ best_H, best_Ireg, best_err = None, None, None # L1 error, normalized by area err_orig = np.mean(np.abs(I - Iref).flatten()) for i, cropx in enumerate(CROPX): cropy = CROPY[i] I_crop = cropout_stuff(I, cropy, cropy, cropx, cropx) Iref_crop = cropout_stuff(Iref, cropy, cropy, cropx, cropx) H, err = imagesAlign.imagesAlign(I_crop, Iref_crop, trfm_type='rigid', rszFac=0.15, applyWarp=False) Ireg = sh.imtransform(I, H) err_galign = np.mean(np.abs(Ireg - Iref).flatten()) err_rel = err_galign / err_orig if err_orig != 0.0 else 0.0 if err_rel <= ERR_REL_THR: return H, Ireg, err_galign elif best_H is None or err_galign < best_err: best_H, best_Ireg, best_err = H, Ireg, err_galign return best_H, best_Ireg, best_err