{"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":"code","source":"# Import libraries and install\n\nimport pandas as pd\nimport numpy as np\nimport matplotlib.pyplot as plt\nfrom matplotlib.patches import Rectangle\nimport matplotlib.image as image\nimport os as os\nimport imageio\nimport tqdm\nfrom tqdm import trange\nimport glob\nimport cv2\nimport scipy.ndimage as ndi\nimport shutil\nfrom PIL import Image\n\n#For the models\nimport keras\nfrom keras import layers\nfrom tensorflow.keras.models import Sequential, Model\nfrom tensorflow.keras.layers import Conv2D, Activation, GlobalAveragePooling2D, Dense, Input\nimport tensorflow as tf\n\n#For EfficientNet\n#!pip install -U efficientnet\n#import efficientnet.keras as efn\n\n#For HPA Cell Segmentator\n#!pip install https://github.com/CellProfiling/HPA-Cell-Segmentation/archive/master.zip\n!pip install \"../input/hpacellsegmentatormaster/HPA-Cell-Segmentation-master\"\nimport hpacellseg.cellsegmentator as cellsegmentator\nfrom hpacellseg.utils import label_cell, label_nuclei\n\n#For encoding masks\n#!pip install pycocotools\n!pip install \"../input/pycocotools/pycocotools-2.0-cp37-cp37m-linux_x86_64.whl\"\nimport base64\nfrom pycocotools import _mask as coco_mask\nimport typing as t\nimport zlib","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"!pip install '../input/kerasapplications'","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"!pip install '../input/efficientnet-keras-source-code'","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import efficientnet.keras as efn ","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"!pip install \"../input/hpapytorchzoozip/pytorch_zoo-master\"","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Input\ncompetition_data_dir = '../input/hpa-single-cell-image-classification'","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#DATAFRAMES - only submission csv used for final submission\n\n# Main dataframe from the train.csv file\nprint('\\033[95m'+'\\033[1m'+'DF (train.csv)')\ndf = pd.read_csv(\"../input/hpa-single-cell-image-classification/train.csv\")\ndf[\"Label\"]=df[\"Label\"].apply(lambda x:x.split(\"|\"))\ndisplay(df)\n\n# df_Labels, the main dataframe separated into individual labels, in a list\ndf_Labels = []\nprint('\\033[95m'+'\\033[1m'+'DF_LABELS')\nfor i in range(0,19):\n    temp_labels = df['Label']\n    df_temp = df.copy()\n    for index,row in df_temp.iterrows():\n        if str(i) in temp_labels[index]:\n            row['Label'] = 1 #np.asarray(1).astype(np.float32)\n        if not str(i) in temp_labels[index]:\n            row['Label'] = 0 #np.asarray(0).astype(np.float32)\n    df_Labels.append(df_temp)\ndisplay(df_Labels[5])\n\n# Base submission csv to dataframe\nprint('\\033[95m'+'\\033[1m'+'SUBMISSION DF (submission.csv)')\ndf_submission = pd.read_csv(\"../input/base-submission-csv-2/submission.csv\")\ndisplay(df_submission)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#TEST IMAGES from test folder - 'images_test'\n# individual lists for red, yellow, blue, green filter paths, but for segmentator we need red, yellow, blue\nred_filters_test = sorted(glob.glob(competition_data_dir + '/test/' + '*_red.png'))\nyellow_filters_test = sorted(glob.glob(competition_data_dir + '/test/' + '*_yellow.png'))\nblue_filters_test = sorted(glob.glob(competition_data_dir + '/test/' + '*_blue.png'))\ngreen_filters_test = sorted(glob.glob(competition_data_dir + '/test/' + '*_green.png'))\n\nimages_test = [red_filters_test, yellow_filters_test, blue_filters_test]#, green_filters_test]\n\nproba = cv2.imread(green_filters_test[0])\nplt.imshow(proba)\nplt.show()\n\n#Read new ids and size of images in test folder for final submission\nids = []\nwidths = []\nheight = []\nfor ids_filters in range(len(red_filters_test)):\n    widths.append(plt.imread(red_filters_test[ids_filters]).shape[1])\n    height.append(plt.imread(red_filters_test[ids_filters]).shape[0])\nfor ids_filters in range(len(red_filters_test)):\n    ids.append(os.path.basename(red_filters_test[ids_filters])[:-8])\ndf_submission = pd.DataFrame(data={'ID': ids, 'ImageWidth': widths, 'ImageHeight': height})","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#We use separate models for each label, models is a list with these efficientnet models\ndef create_models():\n    models = []\n    for i in trange(19):  \n        base_model = efn.EfficientNetB0(weights=None, include_top=False, input_shape=(224, 224, 3))\n\n        model_1 = Sequential()\n        model_1.add(Conv2D(3, (3, 3), padding='same', input_shape=(224, 224, 4)))\n\n        base_model._layers.pop(0)\n\n        model = keras.Sequential([\n        model_1,\n        base_model,\n        layers.GlobalAveragePooling2D(),\n        layers.Dense(128, activation='relu'),\n        layers.Dense(1, activation='sigmoid')    \n        ])\n\n        # Unfreeze the layers\n        for layer in model.layers[0:]:\n            layer.trainable = True\n\n        model.compile(keras.optimizers.Adam(learning_rate=1e-4),loss=\"binary_crossentropy\",metrics=[\"accuracy\"])\n        model.load_weights('../input/models-weights/Models copy/MODEL' + str(i) + '/')\n        models.append(model)\n    return models\n","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#LOAD MODELS\n# Create new model instances\nmodels_loaded = create_models()\n","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#Prepare cell segmentator\nNUC_MODEL = \"../input/hpacellsegmentatormodelweights/dpn_unet_nuclei_v1.pth\"\nCELL_MODEL = \"../input/hpacellsegmentatormodelweights/dpn_unet_cell_3ch_v1.pth\"\n\nsegmentator = cellsegmentator.CellSegmentator(\n    NUC_MODEL,\n    CELL_MODEL,\n    scale_factor=0.25,\n    device=\"cuda\",\n    # NOTE: setting padding=True seems to solve most issues that have been encountered\n    #       during our single cell Kaggle challenge.\n    padding=True,#False,\n    multi_channel_model=True,\n)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#Encode cell mask to submission format (RLE, compress, base64)\ndef encode_binary_mask(mask: np.ndarray) -> t.Text:\n    \"\"\"Converts a binary mask into OID challenge encoding ascii text.\"\"\"\n\n    # check input mask --\n    if mask.dtype != np.bool:\n        raise ValueError(\n           \"encode_binary_mask expects a binary mask, received dtype == %s\" %\n           mask.dtype)\n\n    mask = np.squeeze(mask)\n    if len(mask.shape) != 2:\n        raise ValueError(\n            \"encode_binary_mask expects a 2d mask, received shape == %s\" %\n            mask.shape)\n\n    # convert input mask to expected COCO API input --\n    mask_to_encode = mask.reshape(mask.shape[0], mask.shape[1], 1)\n    mask_to_encode = mask_to_encode.astype(np.uint8)\n    mask_to_encode = np.asfortranarray(mask_to_encode)\n\n    # RLE encode mask --\n    encoded_mask = coco_mask.encode(mask_to_encode)[0][\"counts\"]\n\n    # compress and base64 encoding --\n    binary_str = zlib.compress(encoded_mask, zlib.Z_BEST_COMPRESSION)\n    base64_str = base64.b64encode(binary_str)\n    return base64_str","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import gc\nimport torch","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df.to_csv('submission.csv', index=False)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#Predict\n#cell segmentation, masks, crop cells, get an array of cells\n\nbatch_size = 16\nsubmissions = []\n\nfor i in trange(0, len(images_test[0]), batch_size):\n    # sub_images - one batch of images\n    # cell_masks - masks of one batch of images\n    # cells      - all cells in the batch\n    # predictions - predictions for all cells in the batch\n    # masks      - masks for all cells in the batch\n    # encoded_masks - encoded masks\n   \n    #one batch of images\n    sub_images = [img_channel_list[i:i+batch_size] for img_channel_list in images_test]\n\n    #segment cells\n    cell_segmentations = segmentator.pred_cells(sub_images)\n    nuc_segmentations = segmentator.pred_nuclei(sub_images[2])\n    \n    cell_masks = []\n    # get masks\n    for k, pred in enumerate(cell_segmentations):\n        #get masks from segmentations\n        nuclei_mask, cell_mask = label_cell(nuc_segmentations[k], cell_segmentations[k])\n        cell_masks.append(cell_mask)\n    \n    cells = []\n    #get bboxes\n    for j in range(0,len(cell_masks)):\n        \n        #finding bboxes\n        bboxes = ndi.find_objects(cell_masks[j].astype(np.uint8) )\n      \n        #visualization of bboxes and cropping\n\n        #reading image for visualization\n        path = images_test[0][j+i][:-8]\n        #read filters\n        microtubule = plt.imread(path + \"_red.png\", cv2.IMREAD_GRAYSCALE)   \n        endoplasmicrec = plt.imread(path + \"_yellow.png\", cv2.IMREAD_GRAYSCALE)    \n        nuclei = plt.imread(path + \"_blue.png\", cv2.IMREAD_GRAYSCALE)\n        protein = plt.imread(path + \"_green.png\", cv2.IMREAD_GRAYSCALE)\n        #stack filters, resize later\n        #img =microtubule+ protein+ nuclei+ endoplasmicrec\n        img = np.stack((microtubule, protein, nuclei, endoplasmicrec), axis=-1)\n          \n        for l in range(0, len(bboxes)):\n            #cropping bbox\n            img_cropped = img[bboxes[l]]\n            cells.append(img_cropped)\n    \n    #resize\n    for index_cells in range(0,len(cells)):\n        img_resized = cv2.resize(cells[index_cells],(224, 224))\n        img_resized = np.asarray(img_resized).astype(np.float32)\n        cells[index_cells] = img_resized\n    \n    #PREDICTION\n    list_of_predictions = []\n    for index_models in range(0,19):\n        predictions = models_loaded[index_models].predict(np.asarray(cells))\n        list_of_predictions.append(predictions)\n    \n    #SUBMISSION ENCODING\n    encoded_masks = []\n    for index_masks in range(0,len(cell_masks)):\n        unique_values = np.unique(cell_masks[index_masks])\n        for index_cells in range(1,len(unique_values)):\n            mask = np.where(cell_masks[index_masks]==unique_values[index_cells], 1, 0).astype(np.bool)\n            encoded_mask = encode_binary_mask(mask)\n            encoded_masks.append(encoded_mask)\n    \n    #Create submission rows\n    count = 0 #counter for cells already in the row\n    for index_images in range(0, len(cell_masks)):\n        submission_row = \"\"\n        for index_cells in range(0,len(ndi.find_objects(cell_masks[index_images].astype(np.uint8)))):\n            sub_row_cell = \"\"\n            for index_predictions in range(0,19):\n                sub_row_cell =  sub_row_cell + str(index_predictions) + \" \" + str(list_of_predictions[index_predictions][index_cells+count])[1:-1] + \" \" + str(encoded_masks[index_cells+count])[2:-1] + \" \"\n            submission_row = submission_row + sub_row_cell\n        submissions.append(submission_row)\n        count = count + len(ndi.find_objects(cell_masks[index_images].astype(np.uint8)))\n        \n    gc.collect()\n    torch.cuda.empty_cache()","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#SUBMISSION CSV from dataset and the predicted submissions\ndf_submission_test = df_submission.copy()\ndf_submission_test['PredictionString'] = submissions\n\ndf_submission_test.to_csv('submission.csv', index=False)  ","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df_submission_test","metadata":{"trusted":true},"execution_count":null,"outputs":[]}]}