I have created a Flask backend that can upload an image through an endpoint and it will predict that image through an image model.
@automatic.route('/upload_file', methods=['POST'])def upload_file(): model_config = ModelConfig("users/thushara2@gmail.com/automatic/characters.jpg") pred = model_config.get_predictions() print(pred) return "Predicted"
The Prediction process will go through another Python class called ModelConfig, and the image path should be entered as a constructor parameter.
import cv2import imutilsimport numpy as npfrom keras.models import load_modelfrom keras.preprocessing.image import img_to_arrayclass ModelConfig: def __init__(self, image_path): self.model = load_model('model_config/model.h5') self.image = cv2.imread(image_path) self.labels = self.get_labels() self.predicted = {} @staticmethod def get_labels(): with open("model_config/labels.txt", 'r') as label_file: return label_file.read().splitlines() @staticmethod def sort_contours(contours, method="left-to-right"): reverse = False i = 0 if method == "right-to-left" or method == "bottom-to-top": reverse = True if method == "top-to-bottom" or method == "bottom-to-top": i = 1 bounding_boxes = [cv2.boundingRect(c) for c in contours] (contours, bounding_boxes) = zip(*sorted(zip(contours, bounding_boxes), key=lambda b: b[1][i], reverse=reverse)) return contours, bounding_boxes def get_predictions(self): y, h, x, w = None, None, None, None gray = cv2.cvtColor(self.image, cv2.COLOR_BGR2GRAY) ret, thresh1 = cv2.threshold(gray, 127, 255, cv2.THRESH_BINARY_INV) dilated = cv2.dilate(thresh1, None, iterations=2) contours = cv2.findContours(dilated.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) contours = imutils.grab_contours(contours) contours = self.sort_contours(contours, method="top-to-bottom")[0] # loop over the contours for c in contours: if cv2.contourArea(c) > 10: (x, y, w, h) = cv2.boundingRect(c) roi = gray[y:y + h, x:x + w] thresh = cv2.threshold(roi, 0, 255, cv2.THRESH_BINARY_INV | cv2.THRESH_OTSU)[1] thresh = cv2.resize(thresh, (32, 32), interpolation=cv2.INTER_CUBIC) thresh = thresh.astype("float32") / 255.0 thresh = np.expand_dims(thresh, axis=-1) thresh = thresh.reshape(1, 32, 32, 1) print("making prediction") pred = self.model.predict(thresh) # BUG LINE FOR FLASK print("predicted") pred = np.argmax(pred) label = self.labels[pred] if label in self.predicted: self.predicted.update({label: self.predicted[label] + [roi]}) else: self.predicted.update({label: [roi]}) return self.predicted
When the endpoint is called there is an error message on the line that predicts the image (eg: model.predict(image)) called,
File "D:\Projects\Python\backend\model_config\model_handler.py", line 53, in get_predictions pred = self.model.predict(thresh) ^^^^^^^^^^^^^^^^^^^^^^^^^^File "D:\Projects\Python\backend\.venv\Lib\site-packages\keras\src\utils\traceback_utils.py", line 122, in error_handler raise e.with_traceback(filtered_tb) from None File "C:\Program Files\Python312\Lib\encodings\cp1252.py", line 19, in encode return codecs.charmap_encode(input,self.errors,encoding_table)[0] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^UnicodeEncodeError: 'charmap' codec can't encode characters in position 18-37: character maps to <undefined>
but I have created a test file but it doesn't go through such endpoints. It has successfully predict that image through same lines of code that I have typed in the endpoint request handler file.
from model_config.model_handler import ModelConfigmodel_config = ModelConfig("users/thushara2@gmail.com/automatic/characters.jpg")pred = model_config.get_predictions()print(pred)