{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"pygments_lexer":"ipython3","nbconvert_exporter":"python","version":"3.6.4","file_extension":".py","codemirror_mode":{"name":"ipython","version":3},"name":"python","mimetype":"text/x-python"}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"markdown","source":"## Import thư viện","metadata":{}},{"cell_type":"code","source":"!pip install pyngrok","metadata":{"execution":{"iopub.status.busy":"2021-12-09T00:26:15.401241Z","iopub.execute_input":"2021-12-09T00:26:15.401759Z","iopub.status.idle":"2021-12-09T00:26:26.967591Z","shell.execute_reply.started":"2021-12-09T00:26:15.401665Z","shell.execute_reply":"2021-12-09T00:26:26.966773Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"!pip install streamlit","metadata":{"execution":{"iopub.status.busy":"2021-12-09T00:26:26.969762Z","iopub.execute_input":"2021-12-09T00:26:26.970028Z","iopub.status.idle":"2021-12-09T00:26:38.278197Z","shell.execute_reply.started":"2021-12-09T00:26:26.969992Z","shell.execute_reply":"2021-12-09T00:26:38.277350Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import os\nos.system('pip install /kaggle/input/kerasapplications -q')\nos.system('pip install /kaggle/input/efficientnet-keras-source-code/ -q --no-deps')","metadata":{"execution":{"iopub.status.busy":"2021-12-09T00:26:38.280514Z","iopub.execute_input":"2021-12-09T00:26:38.280834Z","iopub.status.idle":"2021-12-09T00:26:49.830813Z","shell.execute_reply.started":"2021-12-09T00:26:38.280792Z","shell.execute_reply":"2021-12-09T00:26:49.830016Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"%%writefile app.py\nimport ast\nimport cv2\nimport os\nimport numpy as np\nimport pandas as pd\nimport plotly.express as px\nimport urllib.request\nimport tensorflow_hub as hub\nimport tensorflow as tf\nimport streamlit as st\nimport streamlit.components.v1 as components\nimport random\nimport efficientnet.tfkeras as efn\nimport matplotlib.pyplot as plt\nfrom tensorflow.keras.layers import *\nfrom tensorflow.keras.optimizers import *\nfrom tensorflow.keras.models import *\nfrom tensorflow.keras.preprocessing import image\nfrom tensorflow.keras.applications import VGG16, VGG19\n\n\nst.set_page_config(layout=\"centered\", page_title=\"APPLE DISEASES DETECTION\")\nhide_menu_style = \"\"\"\n<style>\nfooter {visibility: hidden;}\n</style>\n\"\"\"\nst.markdown(hide_menu_style, unsafe_allow_html= True)\n\nselect_course = st.sidebar.selectbox(\"Select course\", (\"CS406.M11\", \"CS231.M11\"))\nif select_course == 'CS231.M11':\n    select_model = st.sidebar.selectbox(\"Select model\",(\"EfficientNetB0\", \"EfficientNetB5\", \"EfficientNetB7\", \"EfficientNetV2\", \"VGG16\", \"VGG19\", \"ResNet50-224x224\", \"ResNet50V2-224x224\", \"ResNet50-480x480\", \"ResNet50V2-480x480\"))\n    preprocess = \"None\"\nelse:\n    select_model = st.sidebar.selectbox(\"Select model\",(\"EfficientNetV2-Raw\", \"EfficientNetV2-Geometric\", \"EfficientNetV2-Pixel\", \"EfficientNetV2-Artifacts\", \"EfficientNetV2-FullAug\", \"EfficientNetV2-Geo+Artifact\"))\n    preprocess = st.sidebar.selectbox(\"Select pre-processing function\", (\"None\", \"artifact_preprocess\", \"geometric_preprocess\", \"pixel_preprocess\", \"full_preprocess\"))\n\nif select_model == \"ResNet50-224x224\" or select_model == \"ResNet50V2-224x224\":\n    HEIGHT = 224\n    WIDTH = 224\nelse:\n    HEIGHT = 480\n    WIDTH = 480\nCHANNELS = 3\nCLASSES = 6\ntop_dropout_rate = 0.2\nn_label = ['complex', 'frog_eye_leaf_spot', 'healthy', 'powdery_mildew', 'rust', 'scab']\n\ndef load_image(image_id):\n    file_path = str(image_id)\n    img = cv2.imread(file_path)\n    return cv2.cvtColor(img, cv2.COLOR_BGR2RGB)\n\ndef insect_preprocess(image, p = 0.5, insects_folder='../input/insectdarta/insect'):\n    dark_insect=False\n    n_insects = random.randint(1, 2)\n    aug_prob = random.random()\n    flag = False\n    if aug_prob < p:\n        flag = True\n        height, width, _ = image.shape  # target image width and height\n        insects_images = os.listdir(insects_folder)\n        img_shape = image.shape\n\n        for _ in range(n_insects):\n            insect = cv2.cvtColor(cv2.imread(os.path.join(insects_folder, random.choice(insects_images))), cv2.COLOR_RGB2BGR)\n            insect = cv2.flip(insect, random.choice([-1, 0, 1]))\n            insect = cv2.rotate(insect, random.choice([0, 1, 2]))\n            insect = cv2.resize(insect, (width, height))\n\n            h_height, h_width, _ = insect.shape  # insect image width and height\n            roi_ho = random.randint(0, image.shape[0] - insect.shape[0])\n            roi_wo = random.randint(0, image.shape[1] - insect.shape[1])\n            roi = image[roi_ho:roi_ho + h_height, roi_wo:roi_wo + h_width]\n\n            # Creating a mask and inverse mask \n            img2gray = cv2.cvtColor(insect, cv2.COLOR_BGR2GRAY)\n            ret, mask = cv2.threshold(img2gray, 10, 255, cv2.THRESH_BINARY)\n            #mask_inv = cv2.cvtColor(cv2.bitwise_not(mask),cv2.COLOR_BGR2GRAY)\n            mask_inv = cv2.bitwise_not(mask)\n\n            # Now black-out the area of insect in ROI\n            img_bg = cv2.bitwise_and(roi, roi, mask=mask_inv)\n\n            # Take only region of insect from insect image.\n            if dark_insect:\n                img_bg = cv2.bitwise_and(roi, roi, mask=mask_inv)\n                insect_fg = cv2.bitwise_and(img_bg, img_bg, mask=mask)\n            else:\n                insect_fg = cv2.bitwise_and(insect, insect, mask=mask)\n\n            # Put insect in ROI and modify the target image\n            dst = cv2.add(img_bg, insect_fg, dtype = cv2.CV_64F)\n\n            image[roi_ho:roi_ho + h_height, roi_wo:roi_wo + h_width] = dst\n\n    return image\ndef geometric_preprocess(image):\n    p_spatial = tf.random.uniform([], 0, 1.0, dtype=tf.float32)\n    p_rotate = tf.random.uniform([], 0, 1.0, dtype=tf.float32)\n    p_crop = tf.random.uniform([], 0, 1.0, dtype=tf.float32)\n\n    # Flips\n    image = tf.image.random_flip_left_right(image)\n    image = tf.image.random_flip_up_down(image)\n    if p_spatial > .75:\n        image = tf.image.transpose(image)\n        \n    # Rotates\n    if p_rotate > .75:\n        image = tf.image.rot90(image, k=3) # rotate 270º\n    elif p_rotate > .5:\n        image = tf.image.rot90(image, k=2) # rotate 180º\n    elif p_rotate > .25:\n        image = tf.image.rot90(image, k=1) # rotate 90\n        \n    # Crops\n    if p_crop > .7:\n        if p_crop > .9:\n            image = tf.image.central_crop(image, central_fraction=.7)\n        elif p_crop > .8:\n            image = tf.image.central_crop(image, central_fraction=.8)\n        else:\n            image = tf.image.central_crop(image, central_fraction=.9)\n    elif p_crop > .4:\n        HEIGHT1 = image.shape[0]\n        WIDTH1 = image.shape[1]\n        crop_size_h = tf.random.uniform([], int(HEIGHT1*.8), HEIGHT1, dtype=tf.float32)\n        crop_size_w = tf.random.uniform([], int(WIDTH1*.8), WIDTH1, dtype=tf.float32)\n        image = tf.image.random_crop(image, size=[crop_size_h, crop_size_w, 3])\n\n    return image\ndef pixel_preprocess(image):\n    \n    p_pixel_1 = tf.random.uniform([], 0, 1.0, dtype=tf.float32)\n    p_pixel_2 = tf.random.uniform([], 0, 1.0, dtype=tf.float32)\n    p_pixel_3 = tf.random.uniform([], 0, 1.0, dtype=tf.float32)\n    \n\n    # Pixel-level transforms\n    if p_pixel_1 >= .4:\n        image = tf.image.random_saturation(image, lower=.7, upper=1.3)\n    if p_pixel_2 >= .4:\n        image = tf.image.random_contrast(image, lower=.8, upper=1.2)\n    if p_pixel_3 >= .4:\n        image = tf.image.random_brightness(image, max_delta=.1)\n\n    return image\n\ndef full_preprocess(image):\n    image = insect_preprocess(image, p = 1.0)\n    image = geometric_preprocess(image)\n    image = pixel_preprocess(image)\n    return image\n\ndef process(img, preprocess):\n    if preprocess == \"None\":\n        return cv2.resize(img / 255.0, (HEIGHT, WIDTH)).reshape(-1, HEIGHT, WIDTH, 3)\n    if preprocess == \"full_preprocess\":\n        img = full_preprocess(img)\n    if preprocess == \"artifact_preprocess\":\n        img = insect_preprocess(img, p = 1.0)\n    if preprocess == \"pixel_preprocess\":\n        img = pixel_preprocess(img)\n    if preprocess == \"geometric_preprocess\":\n        img = geometric_preprocess(img)\n    img = tf.cast(img, tf.float32) / 255.0\n    img = np.array(img)\n    return cv2.resize(img, (HEIGHT, WIDTH)).reshape(-1, HEIGHT, WIDTH, 3)\n\n\ndef get_model_V2():\n    hub_url = \"../input/efficientnetv2-tfhub-weight-files/tfhub_models/efficientnetv2-l-21k-ft1k/feature_vector\"\n    \n    model = tf.keras.Sequential([\n            tf.keras.layers.InputLayer(input_shape = [HEIGHT, WIDTH, CHANNELS]),\n            hub.KerasLayer(hub_url, trainable = True),\n            Dropout(top_dropout_rate, name = \"top_dropout\"),\n            Dense(CLASSES, activation = 'sigmoid')\n        ])\n    model.build((HEIGHT, WIDTH, CHANNELS))\n    \n    return model\n\ndef get_model_B7():\n    weights_path = '../input/d/hunhtnthnh/b7tpu/FGVC8-B7-full_aug.h5'\n    base_model = efn.EfficientNetB7(include_top=False, weights='imagenet', input_shape=(HEIGHT, WIDTH, 3), pooling='avg')\n\n    x = base_model.output\n    x = Dense(CLASSES, \n        kernel_initializer=tf.keras.initializers.RandomUniform(seed=32),\n        bias_initializer=tf.keras.initializers.Zeros(), name='dense_top')(x)\n    outputs = Activation('sigmoid', dtype='float32')(x)\n    \n    model = Model(base_model.input, outputs)\n    model.load_weights(weights_path)\n    return model\n\ndef get_model_B5():\n    weights_path = '../input/effnet-b5-model/EfficientNet_B5_Fullaug.h5'\n    base_model = efn.EfficientNetB5(include_top=False, weights=None, input_shape=(HEIGHT, WIDTH, 3))\n    x = base_model.output\n    x = GlobalAveragePooling2D()(x)\n    x = Dropout(top_dropout_rate)(x)\n    outputs = Dense(CLASSES, activation='sigmoid')(x)\n    model = Model(base_model.input, outputs)\n    model.load_weights(weights_path)\n    return model\n\ndef get_model_B0():\n    weights_path = '../input/efficientnetb0/FGVC8-efn-b0.h5'\n    base_model = efn.EfficientNetB0(include_top=False, weights=None, input_shape=(HEIGHT, WIDTH, 3))\n    x = base_model.output\n    x = GlobalAveragePooling2D()(x)\n    x = Dropout(top_dropout_rate)(x)\n    outputs = Dense(CLASSES, activation='sigmoid')(x)\n    model = Model(base_model.input, outputs)\n    model.load_weights(weights_path)\n    return model\n\ndef get_model_VGG16():\n    weights_path = '../input/fgvc8vgg16/FGVC8-VGG16.h5'\n    VGG16_MODEL = VGG16(weights=None ,include_top=False, input_shape=(HEIGHT, WIDTH, 3))\n    \n    x=VGG16_MODEL.output\n    x=GlobalAveragePooling2D()(x)\n    x=Dense(256,activation='relu')(x)\n    x=Dropout(0.2)(x)\n    x=Dense(128,activation='relu')(x)\n    prediction=Dense(6,activation='sigmoid')(x)\n\n    model=Model(inputs=VGG16_MODEL.input, outputs=prediction)\n    model.load_weights(weights_path)\n    return model\n\ndef get_model_VGG19():\n    weights_path = '../input/fgvc8vgg19/FGVC8-VGG19t.h5'\n    VGG19_MODEL = VGG19(weights=None ,include_top=False, input_shape=(HEIGHT, WIDTH, 3))\n    \n    x=VGG19_MODEL.output\n    x=GlobalAveragePooling2D()(x)\n    x=Dense(256,activation='relu')(x)\n    x=Dropout(0.2)(x)\n    x=Dense(128,activation='relu')(x)\n    prediction=Dense(6,activation='sigmoid')(x)\n\n    model=Model(inputs=VGG19_MODEL.input, outputs=prediction)\n    model.load_weights(weights_path)\n    return model\n\ndef plot_probs(outputs):\n    probs = pd.Series(np.round(outputs * 100, 2), n_label)\n    probs = probs.sort_values(ascending=False).reset_index()\n    probs.columns = ['Class', 'Probability']\n    fig = px.bar(probs, x='Class', y='Probability')\n    fig.update_layout(xaxis_tickangle=30)\n    st.plotly_chart(fig, use_container_width=True)\n\nst.markdown(\n    \"<h1 style='text-align: center; color: green;'>IDENTIFY THE CATEGORY OF FOLIAR DISEASES IN APPLE TREES</h1> \",\n    unsafe_allow_html=True\n    )\n\nlogo = plt.imread(\"../input/logoimage/logo.png\")\nst.image(logo)\n\nst.markdown(\n    \"<h1 style='text-align: center;'>Input</h1> \",\n    unsafe_allow_html=True\n    )\n\nuploaded_file = st.file_uploader(\"Choose a file\")\nurl = st.text_input(\n    'Image Url: ', \n    'https://hort.extension.wisc.edu/files/2014/11/CedarAppleRust_apple.png'\n)\nst.write('')\nst.write('')\n\nif preprocess == \"None\":\n    if uploaded_file is not None:\n        bytes_data = uploaded_file.read()\n        st.image(bytes_data, use_column_width=True)\n        with open('./test.jpg', 'wb') as f: \n            f.write(bytes_data)\n    elif url:\n        urllib.request.urlretrieve(url, './test.jpg')\n        st.markdown(\n            f\"<center><img src='{url}' style='width: 95%;'></center>\",\n            unsafe_allow_html=True\n        )\n    img_test = './test.jpg'\n    img = load_image(img_test)\nelse:\n    if uploaded_file is not None:\n        bytes_data = uploaded_file.read()\n        with open('./test.jpg', 'wb') as f: \n            f.write(bytes_data)\n    elif url:\n        urllib.request.urlretrieve(url, './test.jpg')\n        \n    img_test = './test.jpg'\n    img = load_image(img_test)\n    col1, col2 = st.columns(2)\n    with col1:\n        st.header(\"Original Image\")\n        st.image(img)\n    if preprocess == \"artifact_preprocess\":\n        pre_img = insect_preprocess(img, p=1.0)\n        with col2:\n            st.header(\"Artifact Preprocess\")\n            st.image(pre_img)\n    if preprocess == \"geometric_preprocess\":\n        pre_img = np.array(geometric_preprocess(img))\n        with col2:\n            st.header(\"Geometric Preprocess\")\n            st.image(pre_img)\n    if preprocess == \"pixel_preprocess\":\n        pre_img = np.array(pixel_preprocess(img))\n        with col2:\n            st.header(\"Pixel-level Preprocess\")\n            st.image(pre_img)\n    if preprocess == \"full_preprocess\":\n        pre_img = np.array(full_preprocess(img))\n        with col2:\n            st.header(\"Full Preprocess\")\n            st.image(pre_img)\n\nbutton_predict = st.button(\"PREDICT\")\n\nst.markdown(\n    \"<h1 style='text-align: center;'>Output</h1> \",\n    unsafe_allow_html=True\n    )\n\n\nif button_predict == True:\n    if select_model in [\"EfficientNetB0\", \"EfficientNetB5\", \"EfficientNetB7\", \"VGG16\", \"VGG19\", \"ResNet50-224x224\", \"ResNet50V2-224x224\", \"ResNet50-480x480\", \"ResNet50V2-480x480\"]:\n        \n        if select_model == \"EfficientNetB5\":\n            model = get_model_B5()\n            thres = 0.1\n        if select_model == \"EfficientNetB7\":\n            model = get_model_B7()\n            thres = 0.35\n        if select_model == \"EfficientNetB0\":\n            model = get_model_B0()\n            thres = 0.3\n        if select_model == \"VGG16\":\n            model = get_model_VGG16()\n            thres = 0.27\n        if select_model == \"VGG19\":\n            model = get_model_VGG19()\n            thres = 0.27\n        if select_model == \"ResNet50-224x224\":\n            model = load_model(\"../input/resnet50-sub/ResNet50.h5\")\n            thres = 0.3\n        if select_model == \"ResNet50V2-224x224\":\n            model = load_model(\"../input/resnet50v2-submit/ResNet50_V2.h5\")\n            thres = 0.3\n        if select_model == \"ResNet50-480x480\":\n            model = load_model(\"../input/resnet50-480x480-submit/ResNet50_480x480.h5\")\n            thres = 0.3\n        if select_model == \"ResNet50V2-480x480\":\n            model = load_model(\"../input/resnet50v2-480x480-submit/ResNet50V2_480x480.h5\")\n            thres = 0.3\n\n        pred = np.array(model.predict(process(img, preprocess)))[0]\n        answer = []\n        for j in range(len(pred)):\n            if pred[j] > thres:\n                answer.append(n_label[j])\n        if (\"healthy\" in answer) and (len(answer) > 1):\n            answer.remove('healthy')\n        if len(answer) == 0:\n            answer.append('Can Identify This Image')\n        answer = ' '.join(answer)\n    elif select_model == \"EfficientNetV2-Geo+Artifact\":\n        model_1 = get_model_V2()\n        model_2 = get_model_V2()\n        weights_path_1 = '../input/efnet-v2-geoaug-model/EfficientNet_V2_GeoAug.h5'\n        weights_path_2 = '../input/efnet-v2-insectaug-model/EfficientNet_V2_InsectAug.h5'\n        model_1.load_weights(weights_path_1)\n        model_2.load_weights(weights_path_2)\n        pred_1 = model_1.layers[2](model_1.layers[1](model_1.layers[0](process(img, preprocess)))).numpy()[0]\n        pred_2 = model_2.layers[2](model_2.layers[1](model_2.layers[0](process(img, preprocess)))).numpy()[0]\n        pred = (pred_1 + pred_2) / 2\n        answer = []\n        for j in range(len(pred)):\n            if pred[j] > 0.3:\n                answer.append(n_label[j])\n        if (\"healthy\" in answer) and (len(answer) > 1):\n            answer.remove('healthy')\n        if len(answer) == 0:\n            answer.append('Can Identify This Image')\n        answer = ' '.join(answer)\n    else:\n        model = get_model_V2()\n        if select_model == \"EfficientNetV2\" or select_model == \"EfficientNetV2-FullAug\":\n            weights_path = '../input/efficientnetv2model/EfficientNet_V2.h5'\n            model.load_weights(weights_path)\n            thres = 0.2\n        if select_model == \"EfficientNetV2-Geometric\":\n            weights_path = '../input/efnet-v2-geoaug-model/EfficientNet_V2_GeoAug.h5'\n            model.load_weights(weights_path)\n            thres = 0.4\n        if select_model == \"EfficientNetV2-Pixel\":\n            weights_path = '../input/efnet-v2-pixelaug-submit/EfficientNet_V2_PixelAug.h5'\n            model.load_weights(weights_path)\n            thres = 0.2\n        if select_model == \"EfficientNetV2-Artifacts\":\n            weights_path = '../input/efnet-v2-insectaug-model/EfficientNet_V2_InsectAug.h5'\n            model.load_weights(weights_path)\n            thres = 0.2\n        if select_model == \"EfficientNetV2-Raw\":\n            weights_path = '../input/efficientnet-v2-raw-model/EfficientNet_V2_raw.h5'\n            model.load_weights(weights_path)\n            thres = 0.3    \n        pred = model.layers[2](model.layers[1](model.layers[0](process(img, preprocess)))).numpy()[0]\n        answer = []\n        for j in range(len(pred)):\n            if pred[j] > thres:\n                answer.append(n_label[j])\n        if (\"healthy\" in answer) and (len(answer) > 1):\n            answer.remove('healthy')\n        if len(answer) == 0:\n            answer.append('Can Identify This Image')\n        answer = ' '.join(answer)\n\n    st.markdown(f\"**Result:** {answer}\")  \n    plot_probs(pred)\n\n\n","metadata":{"execution":{"iopub.status.busy":"2021-12-09T00:42:49.523393Z","iopub.execute_input":"2021-12-09T00:42:49.526019Z","iopub.status.idle":"2021-12-09T00:42:49.552959Z","shell.execute_reply.started":"2021-12-09T00:42:49.525974Z","shell.execute_reply":"2021-12-09T00:42:49.551983Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"!ngrok authtoken 21wIJPucxNI3RKbv2bMAgRsw08N_YRH3Z1vGpAGLcSYs5YVs","metadata":{"execution":{"iopub.status.busy":"2021-12-09T00:26:49.850810Z","iopub.execute_input":"2021-12-09T00:26:49.851473Z","iopub.status.idle":"2021-12-09T00:26:52.294050Z","shell.execute_reply.started":"2021-12-09T00:26:49.851434Z","shell.execute_reply":"2021-12-09T00:26:52.292982Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from pyngrok import ngrok\n \npublic_url = ngrok.connect('8501')\npublic_url","metadata":{"execution":{"iopub.status.busy":"2021-12-09T00:42:56.324475Z","iopub.execute_input":"2021-12-09T00:42:56.324894Z","iopub.status.idle":"2021-12-09T00:42:57.052144Z","shell.execute_reply.started":"2021-12-09T00:42:56.324853Z","shell.execute_reply":"2021-12-09T00:42:57.050992Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"!streamlit run app.py >/dev/null","metadata":{"execution":{"iopub.status.busy":"2021-12-09T00:42:59.575070Z","iopub.execute_input":"2021-12-09T00:42:59.575650Z","iopub.status.idle":"2021-12-09T01:00:34.016889Z","shell.execute_reply.started":"2021-12-09T00:42:59.575613Z","shell.execute_reply":"2021-12-09T01:00:34.016083Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]}]}