import os import argparse import matplotlib.pyplot as plt from PIL import Image import tensorflow as tf from keras.engine.training import Model from utils.glob import TARGET_IMG_SIZE from utils.glob import CLASS_LABELS import utils.data_manip as manip def classify(image_path: str, classifier_path: str, verbose: bool = False, return_original: bool = True) -> tuple: """ Uses a trained machine learning model to classify an image loaded from disk. :param image_path: Path to the image to be classified. :param classifier_path: Path to the classifier model to be used. :param verbose: Verbose output. :param return_original: Whether to return the original image or the processed image. :return: The original/processed image (PIL.image) and its classification (str). """ im_original = Image.open(image_path) im_processed = manip.remove_transparency(im_original) im_processed = manip.resize_crop(im_processed, TARGET_IMG_SIZE, TARGET_IMG_SIZE) im_processed = manip.normalize_pixels(im_processed) im_processed = tf.expand_dims(im_processed, axis=0) model: Model = tf.keras.models.load_model(classifier_path) pred = model.predict(im_processed, verbose=1 if verbose else 0) pred_class_idx = tf.argmax(pred, axis=1).numpy()[0] pred_class_label = CLASS_LABELS[pred_class_idx] if return_original: return im_original, pred_class_label else: return im_processed, pred_class_label if __name__ == '__main__': ap = argparse.ArgumentParser() ap.add_argument('-f', '--file', required=True, help='the image to be classified') ap.add_argument('-c', '--classifier', default='models/clf-cnn', help='the machine learning model used for classification, defaults: models/clf-cnn') ap.add_argument('-g', '--gui', action='store_true', help='show classification result using GUI') ap.add_argument('-v', '--verbose-level', choices=['0', '1', '2'], default='0', help="verbose level, default: 0") args = vars(ap.parse_args()) verbose_level = int(args['verbose_level']) img = os.path.abspath(args['file']) clf = os.path.abspath(args['classifier']) image, predicted_label = classify(img, clf, False if verbose_level < 2 else True) if args['gui']: fig, ax = plt.subplots(1, 1, num='Flower Image Classifier') ax.imshow(image) ax.set_title( f'{predicted_label}', fontsize=12, weight='bold' ) ax.text( 0.5, -0.08, f'{os.path.relpath(img)}', horizontalalignment='center', verticalalignment='center_baseline', transform=ax.transAxes, fontsize=8, ) ax.axis('off') plt.show() else: if verbose_level == 0: print(predicted_label) else: print( f'Image {os.path.basename(img)} is classified as "{predicted_label}" (model: "{os.path.basename(clf)}")' )