def fun2_xy(xx, ct, bt, ax, ay, a, dist): x_n, y_n, a_k = xx[:NN], xx[NN:2 * NN], xx[2 * NN:] a[mask] = xx[2 * NN:] ax = poly_utils.polyder2d(a, ax, 0) ay = poly_utils.polyder2d(a, ay, 1) # cost: # (features[k] = n, xi, yi, m, xj, yj) # x_m - x_n + x_i - x_j + ux(x_i, y_i) - ux(x_j, y_j) = 0 # y_m - y_n + y_i - y_j + uy(x_i, y_i) - uy(x_j, y_j) = 0 temp1 = x_n[pos_inv[fes[:, 3].astype(np.int)]] - x_n[pos_inv[fes[:, 0].astype(np.int)]] \ + fes[:, 1] - fes[:, 4] \ + polyval2d((fes[:, 1]+xmin)/float(xmax), (fes[:, 2]+ymin)/float(ymax), ax) \ - polyval2d((fes[:, 4]+xmin)/float(xmax), (fes[:, 5]+ymin)/float(ymax), ax) temp2 = y_n[pos_inv[fes[:, 3].astype(np.int)]] - y_n[pos_inv[fes[:, 0].astype(np.int)]] \ + fes[:, 2] - fes[:, 5] \ + polyval2d((fes[:, 1]+xmin)/float(xmax), (fes[:, 2]+ymin)/float(ymax), ay) \ - polyval2d((fes[:, 4]+xmin)/float(xmax), (fes[:, 5]+ymin)/float(ymax), ay) cost = np.sum((temp1**2 + temp2**2) * reg) # integrate: ct = poly_utils.polymul2d(a, a, ct) cost += str_sm * poly_utils.polyint2d(ct, bt, -1., 1., -1., 1.) return cost
def err_poly(xx, ct, bt, ax, ay, a): x_n, y_n, a_k = xx[:NN], xx[NN:2 * NN], xx[2 * NN:] a[mask] = xx[2 * NN:] ax = poly_utils.polyder2d(a, ax, 0) ay = poly_utils.polyder2d(a, ay, 1) ct = poly_utils.polymul2d(a, a, ct) cost = str_sm * poly_utils.polyint2d(ct, bt, -1., 1., -1., 1.) return cost
def err_xy(xx, ct, bt, ax, ay, a): x_n, y_n, a_k = xx[:NN], xx[NN:2 * NN], xx[2 * NN:] a[mask] = xx[2 * NN:] ax = poly_utils.polyder2d(a, ax, 0) ay = poly_utils.polyder2d(a, ay, 1) # cost: # (features[k] = n, xi, yi, m, xj, yj) # x_m - x_n + x_i - x_j + ux(x_i, y_i) - ux(x_j, y_j) = 0 # y_m - y_n + y_i - y_j + uy(x_i, y_i) - uy(x_j, y_j) = 0 temp1 = x_n[pos_inv[fes[:, 3].astype(np.int)]] - x_n[pos_inv[fes[:, 0].astype(np.int)]] \ + fes[:, 1] - fes[:, 4] \ + polyval2d((fes[:, 1]+xmin)/float(xmax), (fes[:, 2]+ymin)/float(ymax), ax) \ - polyval2d((fes[:, 4]+xmin)/float(xmax), (fes[:, 5]+ymin)/float(ymax), ax) temp2 = y_n[pos_inv[fes[:, 3].astype(np.int)]] - y_n[pos_inv[fes[:, 0].astype(np.int)]] \ + fes[:, 2] - fes[:, 5] \ + polyval2d((fes[:, 1]+xmin)/float(xmax), (fes[:, 2]+ymin)/float(ymax), ay) \ - polyval2d((fes[:, 4]+xmin)/float(xmax), (fes[:, 5]+ymin)/float(ymax), ay) return temp1**2 + temp2**2
def calculate_positions_distortions(pos, fes, roi, K): import scipy.optimize import pyximport pyximport.install() import poly_utils from numpy.polynomial.polynomial import polyval2d str_sm = 1.0 N = np.max(pos[:, 0]) NN = len(pos) # here we use [ss, fs] --> [x, y] ordering xmin, xmax = (1 - roi[1] + roi[0]) // 2, (1 + roi[1] - roi[0]) // 2 ymin, ymax = (1 - roi[3] + roi[2]) // 2, (1 + roi[3] - roi[2]) // 2 # we need the pos --> index mapping pos_inv = np.zeros(int(pos[:, 0].max() + 1), dtype=np.uint16) for i, p in enumerate(pos[:, 0]): pos_inv[int(p)] = i a = np.zeros((K, K), dtype=np.float) ax = np.zeros((K, K), dtype=np.float) ay = np.zeros((K, K), dtype=np.float) mask = np.ones_like(a).astype(np.bool) mask[0, 0] = False # no phase offset mask[1, 0] = False # no x-shift mask[0, 1] = False # no y-shift mask[2, 0] = False # no x-scale mask[0, 2] = False # no y-scale ct = np.zeros((2 * K - 1, 2 * K - 1), dtype=np.float) bt = np.zeros((2 * K - 1, ), dtype=np.float) # regularise by distance from the centre dist = ((fes[:, 1]+xmin)/float(xmax))**2 + ((fes[:, 4]+xmin)/float(xmax))**2 \ +((fes[:, 2]+ymin)/float(ymax))**2 + ((fes[:, 5]+ymin)/float(ymax))**2 reg = np.exp(-dist**2 / (8. * 1.0**2)) def fun2_xy(xx, ct, bt, ax, ay, a, dist): x_n, y_n, a_k = xx[:NN], xx[NN:2 * NN], xx[2 * NN:] a[mask] = xx[2 * NN:] ax = poly_utils.polyder2d(a, ax, 0) ay = poly_utils.polyder2d(a, ay, 1) # cost: # (features[k] = n, xi, yi, m, xj, yj) # x_m - x_n + x_i - x_j + ux(x_i, y_i) - ux(x_j, y_j) = 0 # y_m - y_n + y_i - y_j + uy(x_i, y_i) - uy(x_j, y_j) = 0 temp1 = x_n[pos_inv[fes[:, 3].astype(np.int)]] - x_n[pos_inv[fes[:, 0].astype(np.int)]] \ + fes[:, 1] - fes[:, 4] \ + polyval2d((fes[:, 1]+xmin)/float(xmax), (fes[:, 2]+ymin)/float(ymax), ax) \ - polyval2d((fes[:, 4]+xmin)/float(xmax), (fes[:, 5]+ymin)/float(ymax), ax) temp2 = y_n[pos_inv[fes[:, 3].astype(np.int)]] - y_n[pos_inv[fes[:, 0].astype(np.int)]] \ + fes[:, 2] - fes[:, 5] \ + polyval2d((fes[:, 1]+xmin)/float(xmax), (fes[:, 2]+ymin)/float(ymax), ay) \ - polyval2d((fes[:, 4]+xmin)/float(xmax), (fes[:, 5]+ymin)/float(ymax), ay) cost = np.sum((temp1**2 + temp2**2) * reg) # integrate: ct = poly_utils.polymul2d(a, a, ct) cost += str_sm * poly_utils.polyint2d(ct, bt, -1., 1., -1., 1.) return cost def err_poly(xx, ct, bt, ax, ay, a): x_n, y_n, a_k = xx[:NN], xx[NN:2 * NN], xx[2 * NN:] a[mask] = xx[2 * NN:] ax = poly_utils.polyder2d(a, ax, 0) ay = poly_utils.polyder2d(a, ay, 1) ct = poly_utils.polymul2d(a, a, ct) cost = str_sm * poly_utils.polyint2d(ct, bt, -1., 1., -1., 1.) return cost def err_xy(xx, ct, bt, ax, ay, a): x_n, y_n, a_k = xx[:NN], xx[NN:2 * NN], xx[2 * NN:] a[mask] = xx[2 * NN:] ax = poly_utils.polyder2d(a, ax, 0) ay = poly_utils.polyder2d(a, ay, 1) # cost: # (features[k] = n, xi, yi, m, xj, yj) # x_m - x_n + x_i - x_j + ux(x_i, y_i) - ux(x_j, y_j) = 0 # y_m - y_n + y_i - y_j + uy(x_i, y_i) - uy(x_j, y_j) = 0 temp1 = x_n[pos_inv[fes[:, 3].astype(np.int)]] - x_n[pos_inv[fes[:, 0].astype(np.int)]] \ + fes[:, 1] - fes[:, 4] \ + polyval2d((fes[:, 1]+xmin)/float(xmax), (fes[:, 2]+ymin)/float(ymax), ax) \ - polyval2d((fes[:, 4]+xmin)/float(xmax), (fes[:, 5]+ymin)/float(ymax), ax) temp2 = y_n[pos_inv[fes[:, 3].astype(np.int)]] - y_n[pos_inv[fes[:, 0].astype(np.int)]] \ + fes[:, 2] - fes[:, 5] \ + polyval2d((fes[:, 1]+xmin)/float(xmax), (fes[:, 2]+ymin)/float(ymax), ay) \ - polyval2d((fes[:, 4]+xmin)/float(xmax), (fes[:, 5]+ymin)/float(ymax), ay) return temp1**2 + temp2**2 import time x0 = np.concatenate( (pos[:, 1], pos[:, 2], np.zeros(K**2 - 5, dtype=np.float))) d0 = time.time() res = scipy.optimize.minimize(fun2_xy, x0, args=(ct, bt, ax, ay, a, dist), options={'disp': True}) d1 = time.time() print('time to optimise:', d1 - d0, 's') # print the features with the highest error: err = err_xy(res.x, ct, bt, ax, ay, a) err_poly = err_poly(res.x, ct, bt, ax, ay, a) print('features, highest error --> lowest error:') print('total position error:', np.sum(err)) print('total polyint error:', err_poly) i = np.argsort(err)[::-1] for ii in i: print(fes[ii], np.sqrt(err[ii] / 2.)) xx = res.x x_n, y_n = xx[:NN], xx[NN:2 * NN] a[mask] = xx[2 * NN:] ax = poly_utils.polyder2d(a, ax, 0) ay = poly_utils.polyder2d(a, ay, 1) print(res) print('\nss poly coeffs:') print(ax) print('\nfs poly coeffs:') print(ay) pos_out = pos.copy() pos_out[:, 1] = x_n pos_out[:, 2] = y_n i, j = np.ogrid[-1:1:(xmax - xmin) * 1j, -1:1:(ymax - ymin) * 1j] uss = polyval2d(i, j, ax) ufs = polyval2d(i, j, ay) # generate the new feature positions # I_m(xj) = I_n(xi) # O(xj - x_m + u(xj)) = O(xi - x_n + u(xi)) # xj + ux(x_j, y_j) = x_m - x_n + x_i + ux(x_i, y_i) # so we need the inverse of x - ux and y - uy #fes_out = np.empty_like(fes) #for k, fe in enumerate(fes): # xi, yi = fe[1:3] # xj, yj = fe[4:6] # uss_t = i - uss # ufs_t = j - ufs # ind = np.argmin(np.abs(uss_t - x return uss, ufs, pos_out