def fit_homography(src, dst): """ Find 3x3 homography matrix, such that 'src' points are mapped to 'dst' using the linear DLT method. Input data are normalized automatically. src and dst should be 3xN arrays of N (homogeneous) 2d point correspondances return array H, such that (with . the matrix dot product): dst = H . src (up to fitting errors) Code taken from: http://www.janeriksolem.net/search/label/homography of Jan Erik Solem """ if src.shape != dst.shape: raise RuntimeError('number of points do not match') # condition data (important for numerical reasons) # -- source -- src /= src[[2]] # normalize by "projective" coordinates m = _np.mean(src[:2], axis=1) maxstd = _np.max(_np.std(src[:2], axis=1)) + 1e-9 C1 = _np.diag([1 / maxstd, 1 / maxstd, 1]) C1[0:2, 2] = -m / maxstd src = dot(C1, src) # -- destination -- dst /= dst[[2]] # normalize by "projective" coordinates m = _np.mean(dst[:2], axis=1) maxstd = _np.max(_np.std(dst[:2], axis=1)) + 1e-9 C2 = _np.diag([1 / maxstd, 1 / maxstd, 1]) C2[0:2, 2] = -m / maxstd dst = dot(C2, dst) # create matrix for linear method, 2 rows for each correspondence pair nbr_correspondences = src.shape[1] A = _np.zeros((2 * nbr_correspondences, 9)) for i in range(nbr_correspondences): x, y = src[:2, i] u, v = dst[:2, i] A[2 * i] = [-x, -y, -1, 0, 0, 0, u * x, x * y, u] A[2 * i + 1] = [0, 0, 0, -x, -y, -1, v * x, v * y, v] ## for line based homography fitting this requires specific normalization # due to possible projective coordinates==0 #for i in range(nbr_correspondences): # x,y = src[:2,i] # u,v = dst[:2,i] # A[2*i] = [-u, 0, u*x, -v, 0,v*x, -1, 0, x] # A[2*i+1] = [ 0,-u, u*y, 0,-v,v*y, 0,-1, y] U, S, V = _svd(A) H = V[8].reshape((3, 3)) # decondition H = mdot(inv(C2), H, C1) # normalize and return return H / H[2, 2]
def _svd_nondeg(block_dict, nondeg, nondeg_dims, array_of_U, array_of_S, array_of_V): for i in xrange(len(nondeg)): dims = nondeg_dims[i] # U,S,V = _np.linalg.svd(block_dict[nondeg[i][1]].reshape(dims[0]*dims[1],dims[2]*dims[3]), full_matrices=False, compute_uv=True) # U,S,V = _np.linalg.svd(block_dict[nondeg[i][1]].reshape(dims[0]*dims[1],dims[2]*dims[3])) # scipy # U,S,V = _svd(block_dict[nondeg[i][1]].reshape(dims[0]*dims[1],dims[2]*dims[3]) ) try: U,S,V = _svd(block_dict[nondeg[i][1]].reshape(dims[0]*dims[1],dims[2]*dims[3]), full_matrices=False, compute_uv=True, overwrite_a=True) except: # _np.save('/users/kestin0/MYBUGGY/matrix_{0}'.format(_np.random.randint(100000)),block_dict[nondeg[i][1]].reshape(dims[0]*dims[1],dims[2]*dims[3])) print("!!!!!!!!matrix badly conditioned!!!!!!!!!") U,S,V = _svd(block_dict[nondeg[i][1]].reshape(dims[0]*dims[1],dims[2]*dims[3]), full_matrices=False, compute_uv=True, overwrite_a=False, lapack_driver='gesvd') # U,S,V = _svd(block_dict[nondeg[i][1]].reshape(dims[0]*dims[1],dims[2]*dims[3]), full_matrices=False, compute_uv=True, overwrite_a=True, lapack_driver='gesvd') array_of_U.append(U) ; array_of_S.append(S) ; array_of_V.append(V) # del U,S,V pass
def energy_capture(X, thresh, plot=False): """Compute the number of singular values of X needed to surpass a given energy threshold. The energy of j singular values is defined by energy_j = sum(singular_values[:j]) / sum(singular_values). Parameters ---------- X : (n,k) ndarray A matrix of k snapshots. Each column is a single snapshot. thresh : float or list(floats) Energy capture threshold(s). plot : bool If True, plot the singular values and the energy capture against the singular value index. Returns ------- ranks : int or list(int) The number of singular values required to capture more than each energy capture threshold. """ # Check dimensions. if X.ndim != 2: raise ValueError("data X must be two-dimensional") # Calculate singular values and cumulative energy. singular_values = _svd(X, compute_uv=False) svdvals2 = singular_values**2 cumulative_energy = _np.cumsum(svdvals2) / _np.sum(svdvals2) # Determine the points at which the cumulative energy is one_thresh = _np.isscalar(thresh) if one_thresh: thresh = [thresh] barriers = [_np.searchsorted(cumulative_energy, th) + 1 for th in thresh] if plot: # Visualize cumulative energy and threshold value(s). fig, ax = _plt.subplots(1, 1, sharex=True, figsize=(12, 4)) j = _np.arange(1, singular_values.size + 1) ax.semilogy(j, cumulative_energy, 'C1.-', ms=4, zorder=3) ylim = ax.get_ylim() for th, br in zip(thresh, barriers): ax.hlines(th, 1, br, color="black", linewidth=1) ax.vlines(br, ylim[0], th, color="black", linewidth=1) ax.axis((1, j.size) + ylim) ax.set_xlabel(r"Singular value index $j$") ax.set_ylabel(r"Cumulative energy") return barriers[0] if one_thresh else barriers
def _svd_deg(thetaQ, deg, subnewsize, array_of_U, array_of_S, array_of_V): if len(thetaQ._blocks.keys())==0: pass else: datatype = thetaQ._blocks.itervalues().next().dtype # print(subnewsize) for i in xrange(len(deg)): # construct the degenerated matrix thetaDeg = _np.zeros((subnewsize[i][0],subnewsize[i][1]),dtype=datatype) # fill it for it in deg[i][1]: posL = subnewsize[i][2].index((it[0],it[1])) offL = subnewsize[i][3][posL] dimL = subnewsize[i][4][posL] posR = subnewsize[i][5].index((it[2],it[3])) offR = subnewsize[i][6][posR] dimR = subnewsize[i][7][posR] sliceL = slice(offL,offL+dimL[0]*dimL[1]) sliceR = slice(offR,offR+dimR[0]*dimR[1]) thetaDeg[sliceL,sliceR] = thetaQ._blocks[it].reshape(dimL[0]*dimL[1],dimR[0]*dimR[1]) # print("thetaDeg",thetaDeg) # now SVD # U,S,V = _np.linalg.svd(thetaDeg, full_matrices=False, compute_uv=True) # U,S,V = _np.linalg.svd(thetaDeg) # scipy # U,S,V = _svd(thetaDeg) try: U,S,V = _svd(thetaDeg, full_matrices=False, compute_uv=True, overwrite_a=False) except: # _np.save('/users/kestin0/MYBUGGY/matrix_{0}'.format(_np.random.randint(100000)),thetaDeg) print("!!!!!!!!matrix badly conditioned!!!!!!!!!") U,S,V = _svd(thetaDeg, full_matrices=False, compute_uv=True, overwrite_a=True,lapack_driver='gesvd') # U,S,V = _svd(thetaDeg, full_matrices=False, compute_uv=True, overwrite_a=True, lapack_driver='gesvd') array_of_U.append(U) ; array_of_S.append(S) ; array_of_V.append(V) # del U, S, V pass
def fit_affine(src, dst): """ Find 3x3 affine transformation matrix, mapping 'src' points to 'dst'. Input data are normalized automatically. src and dst should be 3xN arrays of N (homogeneous) 2d point correspondances return array H, such that (with . the matrix dot product): dst = H . src (up to fitting errors) Code taken from: http://www.janeriksolem.net/2009/06/affine-transformations-and-warping.html of Jan Erik Solem """ if src.shape != dst.shape: raise RuntimeError, 'number of points do not match' # condition data #-from points- m = _np.mean(src[:2], axis=1) maxstd = _np.max(_np.std(src[:2], axis=1)) C1 = _np.diag([1 / maxstd, 1 / maxstd, 1]) C1[0:2, 2] = -m / maxstd src_cond = dot(C1, src) #-to points- m = _np.mean(dst[:2], axis=1) C2 = C1.copy() #must use same scaling for both point sets C2[0:2, 2] = -m / maxstd dst_cond = dot(C2, dst) # conditioned points have mean zero, so translation is zero A = _np.concatenate((src_cond[:2], dst_cond[:2]), axis=0) U, S, V = _svd(A.T) #create B and C matrices as Hartley-Zisserman (2:nd ed) p 130. tmp = V[:2].T B = tmp[:2] C = tmp[2:4] tmp2 = _np.concatenate((dot(C, pinv(B)), _np.zeros((2, 1))), axis=1) H = _np.vstack((tmp2, [0, 0, 1])) #decondition H = mdot(inv(C2), H, C1) return H / H[2][2]
def significant_svdvals(X, eps, plot=False): """Count the number of singular values of X that are greater than eps. Parameters ---------- X : (n,k) ndarray A matrix of k snapshots. Each column is a single snapshot. eps : float or list(floats) Cutoff value(s) for the singular values of X. plot : bool If True, plot the singular values and the cutoff value(s) against the singular value index. Returns ------- ranks : int or list(int) The number of singular values greater than the cutoff value(s). """ # Check dimensions. if X.ndim != 2: raise ValueError("data X must be two-dimensional") # Calculate the number of singular values above the cutoff value(s). singular_values = _svd(X, compute_uv=False) one_eps = _np.isscalar(eps) if one_eps: eps = [eps] barriers = [_np.count_nonzero(singular_values > ep) for ep in eps] if plot: # Visualize singular values and cutoff value(s). fig, ax = _plt.subplots(1, 1, sharex=True, figsize=(12, 4)) j = _np.arange(1, singular_values.size + 1) ax.semilogy(j, singular_values, 'C0*', ms=4, zorder=3) ylim = ax.get_ylim() for ep, br in zip(eps, barriers): ax.hlines(ep, 1, br, color="black", linewidth=1) ax.vlines(br, ylim[0], ep, color="black", linewidth=1) ax.axis((1, j.size) + ylim) ax.set_xlabel(r"Singular value index $j$") ax.set_ylabel(r"Singular value $\sigma_j$") return barriers[0] if one_eps else barriers
def pod_basis(X, r, mode="simple", **options): """Compute the POD basis of rank r corresponding to the data in X. This function does NOT shift or scale the data before computing the basis. Parameters ---------- X : (n,k) ndarray A matrix of k snapshots. Each column is a single snapshot. r : int The number of POD basis vectors to compute. mode : str The strategy to use for computing the truncated SVD of X. Options: * "simple" (default): Use scipy.linalg.svd() to compute the entire SVD of X, then truncate it to get the first r left singular vectors of X. May be inefficient for very large matrices. * "arpack": Use scipy.sparse.linalg.svds() to compute only the first r left singular vectors of X. This uses ARPACK for the eigensolver. * "randomized": Compute an approximate SVD with a randomized approach using sklearn.utils.extmath.randomized_svd(). This gives faster results at the cost of some accuracy. options Additional paramters for the SVD solver, which depends on `mode`: * "simple": scipy.linalg.svd() * "arpack": scipy.sparse.linalg.svds() * "randomized": sklearn.utils.extmath.randomized_svd() Returns ------- Vr : (n,r) ndarray The first r POD basis vectors of X. Each column is one basis vector. """ if mode == "simple": return _svd(X, full_matrices=False, **options)[0][:, :r] if mode == "arpack": return _svds(X, r, which="LM", **options)[0][:, ::-1] elif mode == "randomized": return _rsvd(X, r, **options)[0][:, ::-1] else: raise NotImplementedError(f"invalid mode '{mode}'")
def __init__(self, data=None, parent=None): # Generic load/init designer-based GUI super(DialogSVD, self).__init__(parent) ### EDIT ### self.ui = Ui_Dialog() ### EDIT ### self.ui.setupUi(self) ### EDIT ### self.ui.pushButtonNext.clicked.connect(self.advance) self.ui.pushButtonPrev.clicked.connect(self.advance) self.ui.pushButtonGoTo.clicked.connect(self.advance) self.ui.pushButtonCancel.clicked.connect(self.reject) self.ui.pushButtonOk.clicked.connect(self.accept) self.ui.pushButtonClear.clicked.connect(self.clear) self.ui.pushButtonApply.clicked.connect(self.applyCheckBoxes) self.ui.pushButtonScript.clicked.connect(self.runScript) self.firstSV = 0 self.spanSV = 6 self.Mlen = 0 self.Nlen = 0 self.Olen = 0 self.data = _np.zeros([self.Mlen, self.Nlen, self.Olen]) self.selected_svs = set() self.ui.lcdSelectedFactors.display(len(self.selected_svs)) self.svWins = [] self.svLabelCheckBoxes = [ self.ui.checkBox, self.ui.checkBox_2, self.ui.checkBox_3, self.ui.checkBox_4, self.ui.checkBox_5, self.ui.checkBox_6 ] for count in range(self.spanSV): self.svWins.append(_MplCanvas(subplot=211)) self.svWins[count].ax[0].axis('Off') self.svWins[count].ax[1].hold('Off') self.ui.gridLayout.addWidget(self.svWins[0], 1, 0) self.ui.gridLayout.addWidget(self.svWins[1], 1, 1) self.ui.gridLayout.addWidget(self.svWins[2], 1, 2) self.ui.gridLayout.addWidget(self.svWins[3], 3, 0) self.ui.gridLayout.addWidget(self.svWins[4], 3, 1) self.ui.gridLayout.addWidget(self.svWins[5], 3, 2) self.reconCurrent = _MplCanvas(subplot=211) self.reconCurrent.ax[0].axis('Off') self.reconCurrent.ax[1].hold('Off') self.reconRemainder = _MplCanvas(subplot=211) self.reconRemainder.ax[0].axis('Off') self.reconRemainder.ax[1].hold('Off') self.ui.verticalLayout_3.insertWidget(1, self.reconCurrent) self.ui.verticalLayout_3.insertWidget(4, self.reconRemainder) for count in range(self.spanSV): self.svLabelCheckBoxes[count].setText('Keep: ' + str(count)) if data is not None: self.data = data if data.ndim == 3: self.Mlen, self.Nlen, self.Olen = data.shape self.reconCurrent.ax[0].imshow(_np.mean(data, axis=-1), interpolation='none', origin='lower') self.reconCurrent.draw() data = data.reshape([-1, self.Olen]) self.svddata = self.SvdData() self.svddata.orig_shape = [self.Mlen, self.Nlen, self.Olen] self.svddata.U, self.svddata.S, self.svddata.Vh = _svd( data, full_matrices=False) self.maxsvs = self.svddata.S.size self.ui.lcdMaxFactors.display(self.maxsvs) self.ui.spinBoxGoTo.setMaximum(self.maxsvs) self.updateCurrentRemainder() #print('U: {}, S: {}, Vh: {}'.format(self.svddata.U.shape, self.svddata.S.shape, self.svddata.Vh.shape)) self.updateSVPlots()
app.setStyle('Cleanlooks') x = _np.linspace(100, 200, 100) y = _np.linspace(200, 300, 100) f = _np.linspace(500,3000,900) Ex = 30*_np.exp((-(f-1750)**2/(200**2))) Spectrum = _np.convolve(_np.flipud(Ex),Ex,mode='same') # hsi = _np.zeros((y.size,x.size,f.size)) # for count in range(y.size): # hsi[count,:,:] = y[count]*_np.random.poisson(_np.dot(x[:,None],Spectrum[None,:])) hsi[count,:,:] = y[count]*_np.dot(x[:,None],Spectrum[None,:]) hsi = 0*hsi + 1j*hsi data = _svd(hsi.reshape((-1,f.size)), full_matrices=False) # Class method route #ret = DialogSVD.main(data, hsi.shape) #print(ret) # Full route obj = _QWidget() svs = DialogSVD.dialogSVD(data, hsi.shape, img_all=hsi.mean(axis=-1), spect_all=hsi.mean(axis=(0,1)) ,parent=obj) print('Factors selected: {}'.format(svs)) ## app.exec_() _sys.exit()
def __init__(self, data=None, parent = None): # Generic load/init designer-based GUI super(DialogSVD, self).__init__(parent) ### EDIT ### self.ui = Ui_Dialog() ### EDIT ### self.ui.setupUi(self) ### EDIT ### self.ui.pushButtonNext.clicked.connect(self.advance) self.ui.pushButtonPrev.clicked.connect(self.advance) self.ui.pushButtonGoTo.clicked.connect(self.advance) self.ui.pushButtonCancel.clicked.connect(self.reject) self.ui.pushButtonOk.clicked.connect(self.accept) self.ui.pushButtonClear.clicked.connect(self.clear) self.ui.pushButtonApply.clicked.connect(self.applyCheckBoxes) self.ui.pushButtonScript.clicked.connect(self.runScript) self.firstSV = 0 self.spanSV = 6 self.Mlen = 0 self.Nlen = 0 self.Olen = 0 self.data = _np.zeros([self.Mlen, self.Nlen, self.Olen]) self.selected_svs = set() self.ui.lcdSelectedFactors.display(len(self.selected_svs)) self.svWins = [] self.svLabelCheckBoxes = [self.ui.checkBox, self.ui.checkBox_2, self.ui.checkBox_3, self.ui.checkBox_4, self.ui.checkBox_5, self.ui.checkBox_6] for count in range(self.spanSV): self.svWins.append(_MplCanvas(subplot=211)) self.svWins[count].ax[0].axis('Off') self.svWins[count].ax[1].hold('Off') self.ui.gridLayout.addWidget(self.svWins[0],1,0) self.ui.gridLayout.addWidget(self.svWins[1],1,1) self.ui.gridLayout.addWidget(self.svWins[2],1,2) self.ui.gridLayout.addWidget(self.svWins[3],3,0) self.ui.gridLayout.addWidget(self.svWins[4],3,1) self.ui.gridLayout.addWidget(self.svWins[5],3,2) self.reconCurrent = _MplCanvas(subplot=211) self.reconCurrent.ax[0].axis('Off') self.reconCurrent.ax[1].hold('Off') self.reconRemainder = _MplCanvas(subplot=211) self.reconRemainder.ax[0].axis('Off') self.reconRemainder.ax[1].hold('Off') self.ui.verticalLayout_3.insertWidget(1,self.reconCurrent) self.ui.verticalLayout_3.insertWidget(4,self.reconRemainder) for count in range(self.spanSV): self.svLabelCheckBoxes[count].setText('Keep: ' + str(count)) if data is not None: self.data = data if data.ndim == 3: self.Mlen, self.Nlen, self.Olen = data.shape self.reconCurrent.ax[0].imshow(_np.mean(data, axis=-1),interpolation='none', origin='lower') self.reconCurrent.draw() data = data.reshape([-1, self.Olen]) self.svddata = self.SvdData() self.svddata.orig_shape = [self.Mlen, self.Nlen, self.Olen] self.svddata.U, self.svddata.S, self.svddata.Vh = _svd(data, full_matrices=False) self.maxsvs = self.svddata.S.size self.ui.lcdMaxFactors.display(self.maxsvs) self.ui.spinBoxGoTo.setMaximum(self.maxsvs) self.updateCurrentRemainder() #print('U: {}, S: {}, Vh: {}'.format(self.svddata.U.shape, self.svddata.S.shape, self.svddata.Vh.shape)) self.updateSVPlots()
app.setStyle('Cleanlooks') x = _np.linspace(100, 200, 100) y = _np.linspace(200, 300, 100) f = _np.linspace(500, 3000, 900) Ex = 30 * _np.exp((-(f - 1750)**2 / (200**2))) Spectrum = _np.convolve(_np.flipud(Ex), Ex, mode='same') # hsi = _np.zeros((y.size, x.size, f.size)) # for count in range(y.size): # hsi[count,:,:] = y[count]*_np.random.poisson(_np.dot(x[:,None],Spectrum[None,:])) hsi[count, :, :] = y[count] * _np.dot(x[:, None], Spectrum[None, :]) hsi = 0 * hsi + 1j * hsi data = _svd(hsi.reshape((-1, f.size)), full_matrices=False) # Class method route #ret = DialogSVD.main(data, hsi.shape) #print(ret) # Full route obj = _QWidget() svs = DialogSVD.dialogSVD(data, hsi.shape, img_all=hsi.mean(axis=-1), spect_all=hsi.mean(axis=(0, 1)), parent=obj) print('Factors selected: {}'.format(svs))