예제 #1
0
def plot_pca(X, y):
    # apply PCA to data
    pca = PCA(n_components=200)
    pca.fit(X, y)

    # plot variance explained by each component
    plt.plot(np.cumsum(pca.explained_variance_ratio_))
    plt.xlabel('Number of PCA components')
    plt.ylabel('Total explained variance ratio')
    plt.grid()

    plt.savefig(get_file('output', 'graphs', 'pca_wing_explained.eps'),
                bbox_inches='tight')
    plt.clf()

    # plot principal component vs angle
    X_t = pca.transform(X)

    plt.scatter(X_t[:, 0].flatten(), y.flatten())
    plt.xlabel('PCA Component 1')
    plt.ylabel('Wing angle (deg)')
    plt.grid()

    plt.savefig(get_file('output', 'graphs', 'pca_wing.eps'),
                bbox_inches='tight')
    plt.clf()
예제 #2
0
def main():
    X = joblib.load(get_file('output', 'data', X_JOBLIB_NAME))
    y = joblib.load(get_file('output', 'data', Y_JOBLIB_NAME))

    for type in ['male', 'female']:
        print('{} fly orientation detector...'.format(type.capitalize()))
        train_once(X, y, type)
예제 #3
0
def plot_pca(X, y, type):
    # apply PCA to data
    pca = PCA(n_components=200)
    pca.fit(X, y)

    # plot variance explained by each component
    plt.plot(np.cumsum(pca.explained_variance_ratio_))
    plt.xlabel('Number of PCA components')
    plt.ylabel('Total explained variance ratio')
    plt.grid()

    plt.savefig(get_file('output', 'graphs', 'pca_orient_{}_explained.eps'.format(type)), bbox_inches='tight')
    plt.clf()

    # show how data are separated by first two principal components
    X_t = pca.transform(X)

    for l, c, m in zip(range(2), ('blue', 'red'), ('o', 'x')):
        plt.scatter(X_t[y == l, 0], X_t[y == l, 1], color=c, label=CATEGORIES[l], alpha=0.5, marker=m)

    plt.legend(loc='upper right')
    plt.xlabel('PCA 1')
    plt.ylabel('PCA 2')
    plt.grid()

    plt.savefig(get_file('output', 'graphs', 'pca_orient_{}.eps'.format(type)), bbox_inches='tight')
    plt.clf()
예제 #4
0
def train_once(X, y):
    clf, X_train, X_test, y_train, y_test = train(X, y)
    report_model_classification(clf, X_train, X_test, y_train, y_test)

    tree.export_graphviz(clf,
                         out_file=get_file('output', 'diagrams',
                                           'tree_is_fly.dot'),
                         feature_names=FEATURES,
                         class_names=CATEGORIES,
                         filled=True,
                         rounded=True,
                         special_characters=True)

    joblib.dump(clf, get_file('output', 'models', CLF_JOBLIB_NAME))
예제 #5
0
def train_once(X, y):
    clf, X_train, X_test, y_train, y_test = train(X, y, plot=True)

    report_model_regression(clf,
                            X_train,
                            X_test,
                            y_train,
                            y_test,
                            units='radians')

    joblib.dump(clf, get_file('output', 'models', CLF_JOBLIB_NAME))
예제 #6
0
def train_once(X, y, type):
    clf, X_train, X_test, y_train, y_test = train(X, y, type, plot=True)
    report_model_classification(clf, X_train, X_test, y_train, y_test)

    joblib.dump(clf, get_file('output', 'models', clf_joblib_name(type)))
예제 #7
0
 def __init__(self, type):
     self.clf = joblib.load(get_file('output', 'models', clf_joblib_name(type)))
     self.hog = make_hog()
예제 #8
0
def main():
    X = joblib.load(get_file('output', 'data', X_JOBLIB_NAME))
    y = joblib.load(get_file('output', 'data', Y_JOBLIB_NAME))

    train_once(X, y)
예제 #9
0
 def __init__(self):
     self.clf = joblib.load(get_file('output', 'models', CLF_JOBLIB_NAME))
def main():
    X, y = load_data()

    joblib.dump(X, get_file('output', 'data', X_JOBLIB_NAME))
    joblib.dump(y, get_file('output', 'data', Y_JOBLIB_NAME))
예제 #11
0
def load_data(tol_radians=0.1):
    hog = make_hog()

    X = []
    y = []

    img_count = 0
    hand_labeled_count = 0

    for anno in tqdm(get_annotations()):
        img = cv2.imread(anno.image_path, 0)

        mask = img_to_mask(img)
        contours = find_contours(img, mask=mask, type='core')

        for contour in contours:
            type = contour_label(anno, contour)
            if type == 'male':
                break
        else:
            continue

        if anno.count('mw') == 2 and anno.has('mh') and anno.has(
                'ma') and anno.has('mp2'):
            mh = anno.get('mh')[0]
            ma = anno.get('ma')[0]
            mp2 = anno.get('mp2')[0]
        else:
            continue

        # make patch, which will compute the angle from the image
        body_patch = crop_to_contour(img, contour)

        # compute angle from labels
        label_angle = np.arctan2(ma[1] - mh[1], mh[0] - ma[0])

        # find out if the image is flipped or not
        rotate_angle = body_patch.estimate_angle()
        diff = abs(angle_diff(rotate_angle, label_angle))

        if diff <= tol_radians:
            pass
        elif np.pi - tol_radians <= diff <= np.pi + tol_radians:
            rotate_angle = rotate_angle + np.pi
        else:
            anno.warn(
                'Could not properly determine whether image is flipped (diff={:0.1f} degrees)'
                .format(degrees(diff)))
            continue

        # find center of fly
        body_center = body_patch.estimate_center(absolute=True)

        # create patch centered on fly
        fly_patch = male_fly_patch(img, mask, body_center, rotate_angle)
        if fly_patch is None:
            continue

        origin = bound_point((body_center[0], body_center[1]), img)
        mp2_rel = [mp2[0] - origin[0], origin[1] - mp2[1]]

        rot_mat = get_rotation_matrix(np.pi / 2 - rotate_angle)
        mp2_rot = rot_mat.dot(mp2_rel)

        wings = []
        for mw in anno.get('mw'):
            wing_rel = [mw[0] - origin[0], origin[1] - mw[1]]
            wing_rot = rot_mat.dot(wing_rel) - mp2_rot
            angle = np.arctan(abs(wing_rot[0]) / abs(wing_rot[1]))

            wings.append({'x': wing_rot[0], 'angle': angle})
        if len(wings) != 2:
            anno.warn('Length of wings is not 2 for some reason, skipping...')
            continue

        if wings[0]['x'] > wings[1]['x']:
            # wing 0 is right, wing 1 is left
            right_wing_angle = wings[0]['angle']
            left_wing_angle = wings[1]['angle']
        else:
            # wing 1 is right, wing 0 is left
            right_wing_angle = wings[1]['angle']
            left_wing_angle = wings[0]['angle']

        # create a hog patches for both wings
        data = []
        data.append({
            'hog_patch': make_hog_patch(fly_patch),
            'angle': right_wing_angle
        })
        data.append({
            'hog_patch': make_hog_patch(fly_patch.flip('horizontal')),
            'angle': left_wing_angle
        })

        # add data to X and y
        for datum in data:
            X.append(patch_to_features(datum['hog_patch'], hog))
            y.append(datum['angle'])
            hand_labeled_count += 1

            if DEBUG:
                plt.imshow(datum['hog_patch'].img)
                plt.show()

        # increment img_count to indicate that this file was actually used
        img_count += 1

    # assemble features
    X = np.array(X, dtype=float)

    # assemble labels
    y = np.array(y, dtype=float)

    print('Used {} annotated images.'.format(img_count))
    print('Used {} hand-labeled wings.'.format(hand_labeled_count))

    report_labels_regression(np.degrees(y),
                             filename=get_file('output', 'graphs',
                                               'labels_wing.eps'),
                             units='Wing Angle (degrees)')

    return X, y