Exemple #1
0
class Classifier(object):
    """docstring for Classifier."""

    FACELET_ORDER = [
        42,
        39,
        36,
        43,
        40,
        37,
        44,
        41,
        38,  # U
        9,
        10,
        11,
        12,
        13,
        14,
        15,
        16,
        17,  # R
        8,
        7,
        6,
        5,
        4,
        3,
        2,
        1,
        0,  # F
        45,
        46,
        47,
        48,
        49,
        50,
        51,
        52,
        53,  # D
        27,
        28,
        29,
        30,
        31,
        32,
        33,
        34,
        35,  # L
        26,
        25,
        24,
        23,
        22,
        21,
        20,
        19,
        18,  # B
    ]

    def __init__(self, face_order='URFDLB'):
        self._fig = pl.figure()
        self._axis = self._fig.add_subplot(111, projection='3d')
        self._face_order = face_order

    def fit(self, raw_colors):
        self._X = [raw_colors[i] for i in Classifier.FACELET_ORDER]

        np.save('X', self._X)
        for label, color in enumerate(self._X):
            color[0], color[2] = color[2], color[0]
            self._axis.scatter(*color, color=color / 384)
        pl.show()

        self._X_pca = PCA(n_components=2).fit_transform(self._X)
        print(self._X_pca)
        np.save('pca', self._X_pca)
        for i, point in enumerate(self._X_pca):
            pl.scatter(*point, color=self._X[i] / 384)
        pl.show()

        centroids = np.array([self._X_pca[i] for i in range(4, 54, 9)])
        for i, point in enumerate(centroids):
            pl.scatter(*point, color=self._X[9 * i + 4] / 384)
        pl.show()

        print(centroids)
        self._model = KMeans(n_clusters=6, init=centroids)
        # self._model = GaussianMixture(n_components=6, means_init=centroids)
        self._model.fit(self._X_pca)

    def fit2(self, raw_colors):
        from sklearn.mixture import GaussianMixture
        self._X = [raw_colors[i] for i in Classifier.FACELET_ORDER]
        for label, color in enumerate(self._X):
            color[0], color[2] = color[2], color[0]
            self._axis.scatter(*color, color=color / 384)
        pl.show()

        centroids = np.array([self._X[i] for i in range(4, 54, 9)])

        print(centroids)
        self._model = GaussianMixture(n_components=6, means_init=centroids)
        self._model.fit(self._X)
        self._X_pca = self._X

    def fit3(self, raw_colors):
        self._X = [raw_colors[i] for i in Classifier.FACELET_ORDER]
        np.save('X', self._X)
        X = np.load('X.npy').astype('uint8')
        for i in range(len(X)):
            X[i][0], X[i][2] = X[i][2], X[i][0]

        X_hsv = X[np.newaxis, ...]
        hsv = cv2.cvtColor(X_hsv, cv2.COLOR_RGB2HSV)[0]
        centroid_id = list(range(4, 54, 9))
        feats = hsv[:, ::2]

        ax = pl.subplot(111)
        for i, c in enumerate(feats):
            if i % 9 == 4:
                # print(type(raw_colors[i]))
                pl.scatter(*feats[i], color=X[i] / 255.0, marker='x')
            else:
                pl.scatter(*feats[i], color=X[i] / 255.0, marker='o')
        pl.show()

        alphas = np.empty((6, 1))
        means = np.empty((6, feats.shape[1]))
        covs = np.empty((6, feats.shape[1], feats.shape[1]))
        for i in range(6):
            mean = feats[9 * i + 4]
            cov = np.array([[0.5 * 10, 0.0], [0.0, 2.5 * 10]])
            alphas[i] = 1 / 6.0
            means[i] = mean
            covs[i] = cov
            print('alpha:', alphas[i])
            print('mean:', mean)
            print('cov:', cov)
        self._gmm = GMM(6, feats, mu=means, sigma=covs, alpha=alphas)
        self._gmm.execute()
        print(self._gmm.alpha)
        print(self._gmm.mu)
        print(self._gmm.sigma)

        self._ans = []
        for xi in feats:
            probas = np.array([
                self._gmm.Normal(xi, self._gmm.mu[k], self._gmm.sigma[k],
                                 len(xi)) for k in range(6)
            ])
            self._ans.append(probas.argmax())
        print(np.array(self._ans).reshape(6, 3, 3))

        def eigsorted(cov):
            vals, vecs = np.linalg.eigh(cov)
            order = vals.argsort()[::-1]
            return vals[order], vecs[:, order]

        nstd = 2
        ax = pl.subplot(111)
        for i, c in enumerate(self._ans):
            if i % 9 == 4:
                pl.scatter(*feats[i],
                           color=X[centroid_id[c]] / 255.0,
                           marker='x')
            else:
                pl.scatter(*feats[i],
                           color=X[centroid_id[c]] / 255.0,
                           marker='o')

        for k in range(6):
            cov = self._gmm.sigma[k]
            vals, vecs = eigsorted(cov)
            theta = np.degrees(np.arctan2(*vecs[:, 0][::-1]))
            w, h = 2 * nstd * np.sqrt(vals)
            ell = mpl.patches.Ellipse(xy=self._gmm.mu[k],
                                      width=w,
                                      height=h,
                                      angle=theta,
                                      color=X[centroid_id[k]] / 255.0,
                                      alpha=0.5)
            ell.set_facecolor(X[centroid_id[k]] / 255.0)
            ax.add_artist(ell)
        for k in range(6):
            cov = covs[k]
            vals, vecs = eigsorted(cov)
            theta = np.degrees(np.arctan2(*vecs[:, 0][::-1]))
            w, h = 2 * nstd * np.sqrt(vals)
            ell = mpl.patches.Ellipse(xy=self._gmm.mu[k],
                                      width=w,
                                      height=h,
                                      angle=theta,
                                      color=X[centroid_id[k]] / 255.0,
                                      alpha=0.5)
            # ell.set_facecolor(X[centroid_id[k]]/255.0)
            ax.add_artist(ell)
        pl.show()

    def get_state(self):
        # if self._X is None:
        #     raise Error('Se debe hacer fit primero.')
        # pred2 = self._model.predict(self._X_pca)
        # state = ''.join([self._face_order[i] for i in pred2])
        # print(state)
        # pred2 = pred2.reshape(-1, 3, 3)
        # print(pred2)
        # return state
        FACES = 'URFDLB'
        state = ''.join([FACES[i] for i in np.array(self._ans).reshape(-1)])
        print(state)
        return state