def rescaleImage(im, imextent, mvx=None, mvy=None, verbose=0, interpolation=None, fig=None): """ Scale image to make pixels at specified resolution Args: im (array): input image imextent (list of 4 floats): coordinates of image region (x0, x1, y0, y1) mvx, mvy (float or None): number of units per pixel requested. If None then keep unchanged Returns: ims (array): transformed image H (array): transformation matrix from units to pixels. H is the homogeneous transform from original to scaled image mvx (float): internal data mvy (float): internal data fx (float): internal data dy (float): internal data """ if interpolation is None: interpolation = cv2.INTER_AREA dxmv = imextent[1] - imextent[0] dymv = imextent[3] - imextent[2] dx = im.shape[1] dy = im.shape[0] mvx0 = dxmv / float(dx - 1) # current unit/pixel mvy0 = dymv / float(dy - 1) if mvy is None: mvy = mvy0 if mvx is None: mvx = mvx0 if im.dtype == np.int64 or im.dtype == np.int32: # opencv cannot handle int32 or int64 in resize im = im.astype(np.float32) # scale factors fw = np.abs((float(mvx0) / mvx)) fh = np.abs((float(mvy0) / mvy)) if verbose: print('rescaleImage: scale factorf x %.4f, factor y %.4f' % (fw, fh)) print('rescaleImage: result unit/pixel x %.4f y %.4f' % (mvx, mvy)) # scale in steps for the horizontal direction if fw < .5: fwx = fw fac = 1 ims = im while fwx < .5: ims = cv2.resize(ims, None, fx=.5, fy=1, interpolation=cv2.INTER_LINEAR) fwx *= 2 fac *= 2 # print('fw %f, fwx %f, fac %f' % (fw, fwx, fac)) ims = cv2.resize(ims, None, fx=fac * fw, fy=fh, interpolation=interpolation) else: ims = cv2.resize(im, None, fx=fw, fy=fh, interpolation=interpolation) H = pgeometry.pg_transl2H([-.5, -.5]).dot( np.diag([fw, fh, 1]).dot(pgeometry.pg_transl2H([.5, .5]))) if fig is not None: plt.figure(fig) plt.clf() plt.subplot(1, 2, 1) plt.imshow(im, interpolation='nearest') plt.subplot(1, 2, 2) plt.imshow(ims, interpolation='nearest') plt.title('scaled') return ims, H, (mvx, mvy, fw, fh)
def straightenImage(im, imextent, mvx=1, mvy=None, verbose=0, interpolation=cv2_interpolation): """ Scale image to make square pixels Arguments --------- im: array input image imextend: list of 4 floats coordinates of image region (x0, x1, y0, y1) mvx, mvy : float number of mV per pixel requested Returns ------- ims: numpy array transformed image (fw, fh, mvx, mvy, H) : data H is the homogeneous transform from original to straightened image """ if cv2 is None: raise Exception( 'opencv is not installed, method straightenImage is not available') dxmv = imextent[1] - imextent[0] dymv = imextent[3] - imextent[2] dx = im.shape[1] dy = im.shape[0] mvx0 = dxmv / float(dx - 1) # mv/pixel mvy0 = dymv / float(dy - 1) if mvy is None: mvy = mvx fw = np.abs((float(mvx0) / mvx)) fh = np.abs((float(mvy0) / mvy)) if fw < .5: fwx = fw fac = 1 ims = im while (fwx < .5): ims = cv2.resize(ims, None, fx=.5, fy=1, interpolation=cv2.INTER_LINEAR) fwx *= 2 fac *= 2 ims = cv2.resize(ims, None, fx=fac * fw, fy=fh, interpolation=interpolation) else: ims = cv2.resize(im, None, fx=fw, fy=fh, interpolation=interpolation) if verbose: print('straightenImage: size %s fx %.4f fy %.4f' % (im.shape, fw, fh)) print('straightenImage: result size %s mvx %.4f mvy %.4f' % (ims.shape, mvx, mvy)) H = pgeometry.pg_transl2H([-.5, -.5]).dot( np.diag([fw, fh, 1]).dot(pgeometry.pg_transl2H([.5, .5]))) return ims, (fw, fh, mvx, mvy, H)