Code for controlling mbed hardware (LED's, motors), as well as code for the Raspberry Pi to run a Support Vector Machine that identifies objects using the Pi camera
Dependencies: mbed Motordriver mbed-rtos PololuLedStrip
Classifier.py@0:e0dbd261724a, 2019-12-05 (annotated)
- Committer:
- arogliero3
- Date:
- Thu Dec 05 20:34:10 2019 -0500
- Revision:
- 0:e0dbd261724a
Adding code to mbed repo
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
arogliero3 | 0:e0dbd261724a | 1 | #!/usr/bin/env python |
arogliero3 | 0:e0dbd261724a | 2 | |
arogliero3 | 0:e0dbd261724a | 3 | import numpy as np |
arogliero3 | 0:e0dbd261724a | 4 | import re |
arogliero3 | 0:e0dbd261724a | 5 | import scipy.stats |
arogliero3 | 0:e0dbd261724a | 6 | from sklearn import svm, metrics, model_selection |
arogliero3 | 0:e0dbd261724a | 7 | from skimage import io, feature, filters, exposure, color |
arogliero3 | 0:e0dbd261724a | 8 | from joblib import dump, load |
arogliero3 | 0:e0dbd261724a | 9 | |
arogliero3 | 0:e0dbd261724a | 10 | |
arogliero3 | 0:e0dbd261724a | 11 | |
arogliero3 | 0:e0dbd261724a | 12 | class ImageClassifier: |
arogliero3 | 0:e0dbd261724a | 13 | |
arogliero3 | 0:e0dbd261724a | 14 | def __init__(self): |
arogliero3 | 0:e0dbd261724a | 15 | self.classifer = None |
arogliero3 | 0:e0dbd261724a | 16 | |
arogliero3 | 0:e0dbd261724a | 17 | def imread_convert(self, f): |
arogliero3 | 0:e0dbd261724a | 18 | return io.imread(f).astype(np.uint8) |
arogliero3 | 0:e0dbd261724a | 19 | |
arogliero3 | 0:e0dbd261724a | 20 | def load_data_from_folder(self, dir): |
arogliero3 | 0:e0dbd261724a | 21 | # read all images into an image collection |
arogliero3 | 0:e0dbd261724a | 22 | ic = io.ImageCollection(dir + "*.bmp", load_func=self.imread_convert) |
arogliero3 | 0:e0dbd261724a | 23 | |
arogliero3 | 0:e0dbd261724a | 24 | # create one large array of image data |
arogliero3 | 0:e0dbd261724a | 25 | data = io.concatenate_images(ic) |
arogliero3 | 0:e0dbd261724a | 26 | |
arogliero3 | 0:e0dbd261724a | 27 | # extract labels from image names |
arogliero3 | 0:e0dbd261724a | 28 | labels = np.array(ic.files) |
arogliero3 | 0:e0dbd261724a | 29 | for i, f in enumerate(labels): |
arogliero3 | 0:e0dbd261724a | 30 | m = re.search("_", f) |
arogliero3 | 0:e0dbd261724a | 31 | labels[i] = f[len(dir):m.start()] |
arogliero3 | 0:e0dbd261724a | 32 | |
arogliero3 | 0:e0dbd261724a | 33 | return (data, labels) |
arogliero3 | 0:e0dbd261724a | 34 | |
arogliero3 | 0:e0dbd261724a | 35 | def extract_image_features(self, data): |
arogliero3 | 0:e0dbd261724a | 36 | # Please do not modify the header above |
arogliero3 | 0:e0dbd261724a | 37 | |
arogliero3 | 0:e0dbd261724a | 38 | # extract feature vector from image data |
arogliero3 | 0:e0dbd261724a | 39 | |
arogliero3 | 0:e0dbd261724a | 40 | ######################## |
arogliero3 | 0:e0dbd261724a | 41 | ######## YOUR CODE HERE |
arogliero3 | 0:e0dbd261724a | 42 | ######################## |
arogliero3 | 0:e0dbd261724a | 43 | |
arogliero3 | 0:e0dbd261724a | 44 | feature_data = [] |
arogliero3 | 0:e0dbd261724a | 45 | |
arogliero3 | 0:e0dbd261724a | 46 | for image in data: |
arogliero3 | 0:e0dbd261724a | 47 | feature_data.append( |
arogliero3 | 0:e0dbd261724a | 48 | feature.hog(image, pixels_per_cell=(25, 25), cells_per_block=(3, 3), feature_vector=True, |
arogliero3 | 0:e0dbd261724a | 49 | block_norm="L2-Hys")) |
arogliero3 | 0:e0dbd261724a | 50 | |
arogliero3 | 0:e0dbd261724a | 51 | # Please do not modify the return type below |
arogliero3 | 0:e0dbd261724a | 52 | return (feature_data) |
arogliero3 | 0:e0dbd261724a | 53 | |
arogliero3 | 0:e0dbd261724a | 54 | def train_classifier(self, train_data, train_labels): |
arogliero3 | 0:e0dbd261724a | 55 | # Please do not modify the header above |
arogliero3 | 0:e0dbd261724a | 56 | |
arogliero3 | 0:e0dbd261724a | 57 | # train model and save the trained model to self.classifier |
arogliero3 | 0:e0dbd261724a | 58 | |
arogliero3 | 0:e0dbd261724a | 59 | ######################## |
arogliero3 | 0:e0dbd261724a | 60 | ######## YOUR CODE HERE |
arogliero3 | 0:e0dbd261724a | 61 | ######################## |
arogliero3 | 0:e0dbd261724a | 62 | |
arogliero3 | 0:e0dbd261724a | 63 | # this param distribution dictionary was obtained from the sklearn documentation page |
arogliero3 | 0:e0dbd261724a | 64 | param_distribution = {'C': scipy.stats.expon(scale=100), 'gamma': scipy.stats.expon(scale=.1), |
arogliero3 | 0:e0dbd261724a | 65 | 'kernel': ['rbf']} |
arogliero3 | 0:e0dbd261724a | 66 | |
arogliero3 | 0:e0dbd261724a | 67 | model = model_selection.RandomizedSearchCV(svm.SVC(), param_distribution, cv=3, n_iter=6) |
arogliero3 | 0:e0dbd261724a | 68 | |
arogliero3 | 0:e0dbd261724a | 69 | self.classifer = model.fit(train_data, train_labels) |
arogliero3 | 0:e0dbd261724a | 70 | |
arogliero3 | 0:e0dbd261724a | 71 | def predict_labels(self, data): |
arogliero3 | 0:e0dbd261724a | 72 | # Please do not modify the header |
arogliero3 | 0:e0dbd261724a | 73 | |
arogliero3 | 0:e0dbd261724a | 74 | # predict labels of test data using trained model in self.classifier |
arogliero3 | 0:e0dbd261724a | 75 | # the code below expects output to be stored in predicted_labels |
arogliero3 | 0:e0dbd261724a | 76 | |
arogliero3 | 0:e0dbd261724a | 77 | ######################## |
arogliero3 | 0:e0dbd261724a | 78 | ######## YOUR CODE HERE |
arogliero3 | 0:e0dbd261724a | 79 | ######################## |
arogliero3 | 0:e0dbd261724a | 80 | |
arogliero3 | 0:e0dbd261724a | 81 | predicted_labels = self.classifer.predict(data) |
arogliero3 | 0:e0dbd261724a | 82 | |
arogliero3 | 0:e0dbd261724a | 83 | # Please do not modify the return type below |
arogliero3 | 0:e0dbd261724a | 84 | return predicted_labels |
arogliero3 | 0:e0dbd261724a | 85 | |
arogliero3 | 0:e0dbd261724a | 86 | |
arogliero3 | 0:e0dbd261724a | 87 | def main(): |
arogliero3 | 0:e0dbd261724a | 88 | img_clf = ImageClassifier() |
arogliero3 | 0:e0dbd261724a | 89 | |
arogliero3 | 0:e0dbd261724a | 90 | # load images |
arogliero3 | 0:e0dbd261724a | 91 | print("Loading Images") |
arogliero3 | 0:e0dbd261724a | 92 | (train_raw, train_labels) = img_clf.load_data_from_folder('./train/') |
arogliero3 | 0:e0dbd261724a | 93 | (test_raw, test_labels) = img_clf.load_data_from_folder('./test/') |
arogliero3 | 0:e0dbd261724a | 94 | |
arogliero3 | 0:e0dbd261724a | 95 | # convert images into features |
arogliero3 | 0:e0dbd261724a | 96 | print("Extracting features from images") |
arogliero3 | 0:e0dbd261724a | 97 | train_data = img_clf.extract_image_features(train_raw) |
arogliero3 | 0:e0dbd261724a | 98 | test_data = img_clf.extract_image_features(test_raw) |
arogliero3 | 0:e0dbd261724a | 99 | |
arogliero3 | 0:e0dbd261724a | 100 | # train model and test on training data |
arogliero3 | 0:e0dbd261724a | 101 | print("Training Model") |
arogliero3 | 0:e0dbd261724a | 102 | img_clf.train_classifier(train_data, train_labels) |
arogliero3 | 0:e0dbd261724a | 103 | predicted_labels = img_clf.predict_labels(train_data) |
arogliero3 | 0:e0dbd261724a | 104 | print("\nTraining results") |
arogliero3 | 0:e0dbd261724a | 105 | print("=============================") |
arogliero3 | 0:e0dbd261724a | 106 | print("Confusion Matrix:\n", metrics.confusion_matrix(train_labels, predicted_labels)) |
arogliero3 | 0:e0dbd261724a | 107 | print("Accuracy: ", metrics.accuracy_score(train_labels, predicted_labels)) |
arogliero3 | 0:e0dbd261724a | 108 | print("F1 score: ", metrics.f1_score(train_labels, predicted_labels, average='micro')) |
arogliero3 | 0:e0dbd261724a | 109 | |
arogliero3 | 0:e0dbd261724a | 110 | # test model |
arogliero3 | 0:e0dbd261724a | 111 | predicted_labels = img_clf.predict_labels(test_data) |
arogliero3 | 0:e0dbd261724a | 112 | print("\nTest results") |
arogliero3 | 0:e0dbd261724a | 113 | print("=============================") |
arogliero3 | 0:e0dbd261724a | 114 | print("Confusion Matrix:\n", metrics.confusion_matrix(test_labels, predicted_labels)) |
arogliero3 | 0:e0dbd261724a | 115 | print("Accuracy: ", metrics.accuracy_score(test_labels, predicted_labels)) |
arogliero3 | 0:e0dbd261724a | 116 | print("F1 score: ", metrics.f1_score(test_labels, predicted_labels, average='micro')) |
arogliero3 | 0:e0dbd261724a | 117 | |
arogliero3 | 0:e0dbd261724a | 118 | dump(img_clf, "model.joblib") |
arogliero3 | 0:e0dbd261724a | 119 | |
arogliero3 | 0:e0dbd261724a | 120 | |
arogliero3 | 0:e0dbd261724a | 121 | if __name__ == "__main__": |
arogliero3 | 0:e0dbd261724a | 122 | main() |