Created
May 21, 2021 02:40
-
-
Save nvg/16b5bc144d20bc6c3c478178879705b6 to your computer and use it in GitHub Desktop.
Sample Python Server
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| import io | |
| import flask | |
| import keras.applications | |
| import numpy as np | |
| from PIL import Image | |
| from keras.layers import Input | |
| from keras.layers.core import Dense | |
| from keras.models import Model | |
| from skimage.transform import resize | |
| # initialize our Flask application and the Keras model | |
| app = flask.Flask(__name__) | |
| model = None | |
| class_names = ['Atelectasis', 'Cardiomegaly', 'Effusion', 'Infiltration', 'Mass', 'Nodule', 'Pneumonia', | |
| 'Pneumothorax', 'Consolidation', 'Edema', 'Emphysema', 'Fibrosis', 'Pleural_Thickening', 'Hernia'] | |
| def load_model(): | |
| """ | |
| Initializes the model and loads the weights | |
| """ | |
| global model | |
| input_shape = (224, 224, 3) | |
| img_input = Input(shape=input_shape) | |
| x = keras.applications.DenseNet121( | |
| include_top=False, | |
| input_tensor=img_input, | |
| input_shape=input_shape, | |
| weights=None, | |
| pooling="avg").output | |
| predictions = Dense(len(class_names), activation="sigmoid", name="predictions")(x) | |
| model = Model(inputs=img_input, outputs=predictions) | |
| model.load_weights("./weights.h5") | |
| return model | |
| def prepare_image(image, target): | |
| """ | |
| Prepares the image by converting to RGB, normalizing to grayscale and resizing to the target dimensions | |
| @param image image image to prepare | |
| @param target target dimension of the image | |
| @return string formatted string | |
| """ | |
| if image.mode != "RGB": | |
| image = image.convert("RGB") | |
| image_array = np.asarray(image) | |
| image_array = image_array / 255. | |
| image_array = resize(image_array, target) | |
| image_array = np.asarray([image_array]) | |
| imagenet_mean = np.array([0.485, 0.456, 0.406]) | |
| imagenet_std = np.array([0.229, 0.224, 0.225]) | |
| image_array = (image_array - imagenet_mean) / imagenet_std | |
| return image_array | |
| @app.route("/predict", methods=["POST"]) | |
| def predict(): | |
| # initialize the data dictionary that will be returned from the | |
| # view | |
| data = {"success": False} | |
| # ensure an image was properly uploaded to our endpoint | |
| if flask.request.method != "POST": | |
| return flask.jsonify({"success": False, "message": f"Method ${flask.request.method} is not allowed"}) | |
| image_request_param = flask.request.files.get("image") | |
| if image_request_param is None: | |
| return flask.jsonify({"success": False, "message": "Unable to find 'image' parameter"}) | |
| # read the image in PIL format | |
| image = flask.request.files["image"].read() | |
| image = Image.open(io.BytesIO(image)) | |
| # preprocess the image and prepare it for classification | |
| image = prepare_image(image, target=(224, 224)) | |
| # classify the input image and then initialize the list | |
| # of predictions to return to the client | |
| predictions = model.predict(image) | |
| data["predictions"] = [] | |
| # loop over the results and add them to the list of | |
| # returned predictions | |
| for i in range(len(class_names)): | |
| r = {"label": class_names[i], "probability": round(float(predictions[0][i]), 3)} | |
| data["predictions"].append(r) | |
| # indicate that the request was a success | |
| data["success"] = True | |
| # return the data dictionary as a JSON response | |
| return flask.jsonify(data) | |
| if __name__ == "__main__": | |
| load_model() | |
| # Keras throws strange errors in a multi-threaded environment | |
| app.run(threaded=False) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment