def get_stain_matrix(I, beta=0.15, alpha=1): """ Get stain matrix (2x3) :param I: :param beta: :param alpha: :return: """ OD = ut.RGB_to_OD(I).reshape((-1, 3)) OD = (OD[(OD > beta).any(axis=1), :]) _, V = np.linalg.eigh(np.cov(OD, rowvar=False)) V = V[:, [2, 1]] if V[0, 0] < 0: V[:, 0] *= -1 if V[0, 1] < 0: V[:, 1] *= -1 That = np.dot(OD, V) phi = np.arctan2(That[:, 1], That[:, 0]) minPhi = np.percentile(phi, alpha) maxPhi = np.percentile(phi, 100 - alpha) v1 = np.dot(V, np.array([np.cos(minPhi), np.sin(minPhi)])) v2 = np.dot(V, np.array([np.cos(maxPhi), np.sin(maxPhi)])) if v1[0] > v2[0]: HE = np.array([v1, v2]) else: HE = np.array([v2, v1]) return ut.normalize_rows(HE)
def get_stain_matrix(I, threshold=0.8, lamda=0.1): """ Get 2x3 stain matrix. First row H and second row E :param I: :param threshold: :param lamda: :return: """ mask = ut.notwhite_mask(I, thresh=threshold).reshape((-1,)) OD = ut.RGB_to_OD(I).reshape((-1, 3)) OD = OD[mask] dictionary = spams.trainDL(OD.T, K=2, lambda1=lamda, mode=2, modeD=0, posAlpha=True, posD=True, verbose=False).T if dictionary[0, 0] < dictionary[1, 0]: dictionary = dictionary[[1, 0], :] dictionary = ut.normalize_rows(dictionary) return dictionary