{"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":"!cp /kaggle/input/gdcm-conda-install/gdcm.tar .\n!tar -xvzf gdcm.tar\n!conda install --offline ./gdcm/gdcm-2.8.9-py37h71b2a6d_0.tar.bz2\n!rm -rf ./gdcm.tar\n!pip install pandarallel\n\nprint(\"... PIP/APT INSTALLS COMPLETE ...\\n\")\n","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","execution":{"iopub.status.busy":"2021-08-05T23:46:20.688454Z","iopub.execute_input":"2021-08-05T23:46:20.688919Z","iopub.status.idle":"2021-08-05T23:47:00.066787Z","shell.execute_reply.started":"2021-08-05T23:46:20.688881Z","shell.execute_reply":"2021-08-05T23:47:00.065577Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Other Competition Related Imports\nimport pydicom\nfrom pydicom.pixel_data_handlers.util import apply_voi_lut\nfrom pandarallel import pandarallel; pandarallel.initialize();\nimport tensorflow as tf\nimport tensorflow_addons as tfa\nimport os\nimport shutil\nimport gc\nimport cv2\nimport random\nimport glob\nimport numpy as np\nimport pandas as pd\nfrom PIL import Image\nfrom tqdm import tqdm\nfrom shutil import copyfile\nimport matplotlib.pyplot as plt","metadata":{"execution":{"iopub.status.busy":"2021-08-05T22:18:40.788306Z","iopub.execute_input":"2021-08-05T22:18:40.788683Z","iopub.status.idle":"2021-08-05T22:18:45.727413Z","shell.execute_reply.started":"2021-08-05T22:18:40.788626Z","shell.execute_reply":"2021-08-05T22:18:45.726469Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"### Seeding - Attempt to be reproducible ###\n\ndef seed_it_all(seed=7):\n    \"\"\" Attempt to be Reproducible \"\"\"\n    os.environ['PYTHONHASHSEED'] = str(seed)\n    random.seed(seed)\n    np.random.seed(seed)\n    tf.random.set_seed(seed)\n\nseed_it_all()","metadata":{"execution":{"iopub.status.busy":"2021-08-05T22:18:45.728978Z","iopub.execute_input":"2021-08-05T22:18:45.729349Z","iopub.status.idle":"2021-08-05T22:18:45.737435Z","shell.execute_reply.started":"2021-08-05T22:18:45.729313Z","shell.execute_reply":"2021-08-05T22:18:45.736535Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Connect the Dataset","metadata":{}},{"cell_type":"code","source":"base_path = '../input/siim-covid19-detection'\n\nprint('Directories:')\nprint('\\n'.join([dir for dir in os.listdir(base_path) if os.path.isdir(os.path.join(base_path, dir))]))\nprint('\\nFiles:')\nprint('\\n'.join([dir for dir in os.listdir(base_path) if not os.path.isdir(os.path.join(base_path, dir))]))\nTRAIN_PATH = os.path.join(base_path, \"train\")\nTEST_PATH = os.path.join(base_path, \"test\")\n\nimage_test_paths = glob.glob(os.path.join(TEST_PATH, \"*/*/*\"))\nprint(len(image_test_paths))","metadata":{"_kg_hide-output":true,"execution":{"iopub.status.busy":"2021-08-05T22:18:46.146224Z","iopub.execute_input":"2021-08-05T22:18:46.146565Z","iopub.status.idle":"2021-08-05T22:18:50.592903Z","shell.execute_reply.started":"2021-08-05T22:18:46.146533Z","shell.execute_reply":"2021-08-05T22:18:50.59112Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"### read sample submission csv ### \n# Read the submisison file\nsub_df = pd.read_csv('/kaggle/input/siim-covid19-detection/sample_submission.csv')\nprint(len(sub_df))\nsub_df.head()","metadata":{"execution":{"iopub.status.busy":"2021-08-05T22:18:50.594552Z","iopub.execute_input":"2021-08-05T22:18:50.595019Z","iopub.status.idle":"2021-08-05T22:18:50.632204Z","shell.execute_reply.started":"2021-08-05T22:18:50.59498Z","shell.execute_reply":"2021-08-05T22:18:50.631092Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"## we're mainly just focusing on the study-levels ## \nstudylvl_df = sub_df.loc[sub_df.id.str.contains('_study')]\nprint(f\"Amount of Study rows in Sample Submission:          {len(studylvl_df)}\")\n\n# but we'll concatenate this later \nimagelvl_df = sub_df.loc[sub_df.id.str.contains('_image')]\nprint(f\"Amount of Image-level rows in Sample Submission:    {len(imagelvl_df)}\")","metadata":{"execution":{"iopub.status.busy":"2021-08-05T22:18:53.785351Z","iopub.execute_input":"2021-08-05T22:18:53.785796Z","iopub.status.idle":"2021-08-05T22:18:53.803053Z","shell.execute_reply.started":"2021-08-05T22:18:53.78575Z","shell.execute_reply":"2021-08-05T22:18:53.802197Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"####### IMAGE PREPARATION FUNCTIONS ##########\n\n### * dicom2array(): converts dicoms to arrays\n### * reshape_square(): reshapes each example into a N x N square\n\n#Define a function that uses `pydicom` to properly turn dicom files \n#into numpy arrays that are viewable in matplotlib. Code stolen from Darien Schettler\n\ndef dicom2array(path, voi_lut=True, fix_monochrome=True):\n    \"\"\" Convert dicom file to numpy array \n    \n    Args:\n        path (str): Path to the dicom file to be converted\n        voi_lut (bool): Whether or not VOI LUT is available\n        fix_monochrome (bool): Whether or not to apply monochrome fix\n        \n    Returns:\n        Numpy array of the respective dicom file \n        \n    \"\"\"\n    # Use the pydicom library to read the dicom file\n    dicom = pydicom.read_file(path)\n    \n    # VOI LUT (if available by DICOM device) is used to \n    # transform raw DICOM data to \"human-friendly\" view\n    if voi_lut:\n        data = apply_voi_lut(dicom.pixel_array, dicom)\n    else:\n        data = dicom.pixel_array\n        \n    # The XRAY may look inverted\n    #   - If we want to fix this we can\n    if fix_monochrome and dicom.PhotometricInterpretation == \"MONOCHROME1\":\n        data = np.amax(data) - data\n    \n    # Normalize the image array and return\n    data = (data-np.min(data))/(np.max(data)-np.min(data))\n    \n    return data\n\ndef resize_square_from_array(array, pixels, save_dir=None):\n\n    \"\"\"\n    A function that both scales down and crops images to make them square. Takes in some rectangular \n    image and the desired side length of the image. \n\n    The function essentially finds the shorter side of the image, and scales the whole image down\n    preserving aspect ratio so that the length of the smaller side and the desired pixels is the same.\n    Then it crops the rest of the image evenly on both sides to make sure the longer side is also = pixels.\n\n    ARGS:\n\n    array (np.ndarray):  An image represented with a numpy array\n    pixels (int):        the side length of the square image you want.\n\n    KWARGS: \n    save_dir (path):     path to directory you want to save your image to.\n\n    \"\"\"\n    \n    image = Image.fromarray(np.uint8(array*255),mode='L')\n\n#     #plt.imshow(image)\n#     image = Image.open(image) \n    \n    orig_width, orig_height =  image.size\n\n    # get larger and smaller sides\n    smaller_side = min(orig_width, orig_height)\n\n    # make the scale factor from the smaller side so we won't create an image that is too small\n    scale_factor = pixels/smaller_side\n\n    # shrink down image with same aspect ratio\n    image.thumbnail((int(scale_factor*orig_width), int(scale_factor*orig_height)))\n    new_width, new_height = image.size\n\n    # now crop the larger side to make it a square image\n    padding = (abs(new_height - new_width))/2\n\n    if smaller_side==orig_height:\n        upper_left_point = (padding, 0)\n        lower_right_point = (new_width - padding, new_height)\n\n    elif smaller_side==orig_width:\n        upper_left_point = (0, padding)\n        lower_right_point = (new_width, new_height-padding)\n\n    image = image.crop(upper_left_point + lower_right_point)\n\n    return image\n","metadata":{"execution":{"iopub.status.busy":"2021-08-05T22:18:56.377795Z","iopub.execute_input":"2021-08-05T22:18:56.378162Z","iopub.status.idle":"2021-08-05T22:18:56.388796Z","shell.execute_reply.started":"2021-08-05T22:18:56.378133Z","shell.execute_reply":"2021-08-05T22:18:56.387831Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"IMG_SIZE = 512\ntest_folder = '../input/siim-covid19-detection/test'\nnew_test_folder = './test_images'\n\ndef all_in_one_preparations(test_folder, new_test_folder):\n    \n    \"\"\"\n    Simultaneously copy all files over to a writable folder, convert them into pngs, \n    AND record image paths and all that good stuff to put into the master csv. \n    \n    ARGS:\n    \n    test_folder (path): Where all the test dicoms are held (from dataset)\n    new_test_folder (path): Where to put all the converted images\n\n    \"\"\"\n    master_image_ids = []\n    master_study_ids = []\n    master_imglevel_paths = []\n    master_img_size = []\n    dim0 = []\n    dim1 = []\n    \n    i = 0\n    test_images_dir = './test_images'\n    os.makedirs(new_test_folder, exist_ok=True)\n    \n    # study level iterator (iterates 1214 times)\n    for study in tqdm(os.listdir(test_folder)):\n        study_dir = os.path.join(test_folder, (study + \"/\"))\n        \n        # add study to study column\n        master_study_ids.append(study)\n        \n        # make image level list and pathlist for this study (in case more than 1 image)\n        study_images = []\n        study_img_paths = []\n        img_sizes = []\n        \n        \n        #series level iterator (not significant, 1214 times)\n        for series in os.listdir(study_dir):\n            series_dir = os.path.join(study_dir, (series + \"/\"))\n            \n            #image level iterator (1263 times)\n            for image in os.listdir(series_dir):\n                \n                image_path = os.path.join(series_dir, image)\n                study_images.append(image.replace('.dcm', ''))\n                \n                # convert and reshape\n                \n                xray = dicom2array(os.path.join(image_path)) # convert to png\n                img_sizes.append(xray.shape)\n                im = resize_square_from_array(xray, pixels=IMG_SIZE) # reshape\n                new_image_path = os.path.join(new_test_folder, image.replace('.dcm', '.png')) #define new path for conv. img\n                im.save(os.path.join(new_image_path)) # save image to that path\n                \n                #append new path to img path list\n                study_img_paths.append(new_image_path)\n            \n        master_image_ids.append(study_images)\n        master_imglevel_paths.append(study_img_paths)\n        master_img_size.append(img_sizes)\n        \n        \n    return master_study_ids, master_image_ids, master_imglevel_paths, master_img_size\n             \n                \nstudy_ids, image_ids, imglevel_paths, image_sizes = all_in_one_preparations(test_folder, new_test_folder)","metadata":{"execution":{"iopub.status.busy":"2021-08-05T22:19:00.547719Z","iopub.execute_input":"2021-08-05T22:19:00.548055Z","iopub.status.idle":"2021-08-05T22:27:23.751438Z","shell.execute_reply.started":"2021-08-05T22:19:00.548028Z","shell.execute_reply":"2021-08-05T22:27:23.750327Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"amount_of_classes_should_be = len(os.listdir(test_folder))\namount_of_transfered_images = len(os.listdir('./test_images'))\n\nprint(f\"Amount of Images Transfered: {amount_of_transfered_images} images for {amount_of_classes_should_be} classes\")","metadata":{"execution":{"iopub.status.busy":"2021-08-05T22:28:42.169875Z","iopub.execute_input":"2021-08-05T22:28:42.170189Z","iopub.status.idle":"2021-08-05T22:28:42.18209Z","shell.execute_reply.started":"2021-08-05T22:28:42.170162Z","shell.execute_reply":"2021-08-05T22:28:42.181056Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"########## create a master csv with the following columns ##########\n\n# * study ID \n# * one image associated with the study (if multiple, chose one)\n# * path to that chosen image. \ndhruv_master_df = pd.DataFrame(list(zip(study_ids, image_ids, imglevel_paths,image_sizes)),\n                         columns =['study_id', 'image_id', 'image_paths','og_image_sizes'])\nmaster_df = pd.DataFrame(list(zip(study_ids, image_ids, imglevel_paths)),\n                         columns =['study_id', 'image_id', 'image_paths'])\n\n# since there will be a few duplicate rows in the dataframe since \n# the iterator goes by image id and not by class \n\n\nprint(f\"Amount of Rows in Dataset (should be {amount_of_classes_should_be}): {len(master_df.index)}\\n\")\n\nprint(\"Master Dataset Preview\\n===============================================================================\")\nmaster_df","metadata":{"execution":{"iopub.status.busy":"2021-08-05T22:28:44.016368Z","iopub.execute_input":"2021-08-05T22:28:44.01676Z","iopub.status.idle":"2021-08-05T22:28:44.046951Z","shell.execute_reply.started":"2021-08-05T22:28:44.016707Z","shell.execute_reply":"2021-08-05T22:28:44.046151Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"dhruv_master_df","metadata":{"execution":{"iopub.status.busy":"2021-08-05T22:28:47.001932Z","iopub.execute_input":"2021-08-05T22:28:47.002262Z","iopub.status.idle":"2021-08-05T22:28:47.034003Z","shell.execute_reply.started":"2021-08-05T22:28:47.002233Z","shell.execute_reply":"2021-08-05T22:28:47.032954Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from IPython.display import Image\nImage(filename='./test_images/0026720152f5.png') ","metadata":{"execution":{"iopub.status.busy":"2021-08-05T18:37:39.904915Z","iopub.execute_input":"2021-08-05T18:37:39.905257Z","iopub.status.idle":"2021-08-05T18:37:39.922608Z","shell.execute_reply.started":"2021-08-05T18:37:39.905226Z","shell.execute_reply":"2021-08-05T18:37:39.921832Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"###########################################\n####### STUDY LEVEL CLASSIFICATION ########\n###########################################\n\n#### Make a copy of the master_csv with only one image per study ####\n# to make things easy, just pick the first image if there are multiple images for a study.\n\n\nstudy_df = master_df.copy()\n\n# just chose the first image for each study\nstudy_df[\"image_id\"] = study_df.apply(lambda x: x[\"image_id\"][0], axis=1)\n\n# just chose the first path for each study (corresponds to the first image)\nstudy_df[\"image_paths\"] = study_df.apply(lambda x: x[\"image_paths\"][0], axis=1)\n\nprint(\"Edited Master Dataframe for Study-Level Classification\")\nprint(\"========================================================\")\ndisplay(study_df)\n\n#### Create a Test tf.Data.Dataset from File Paths ####\n\n# this will obviously have no augments or even batches since we are not training\n# we are just evaluating\n\ntest_img_paths = list(study_df[\"image_paths\"])\n\n### DEFINE A FUNCITON TO LOAD IMAGES FROM PATH #######\n# more informatino on this functino can be found on accompanying colab notebooks\n\nINPUT_SHAPE = (512, 512, 3)\n\ndef tf_load_image(path, resize_to=INPUT_SHAPE):\n    img_bytes = tf.io.read_file(path)\n    img = tf.image.decode_png(img_bytes, channels=resize_to[-1])\n    img = tf.image.resize(img, resize_to[:-1])\n    img = tf.cast(img, tf.uint8)\n    return img\n\ntest_img_ds = tf.data.Dataset.from_tensor_slices(test_img_paths)\ntest_img_ds = test_img_ds.map(lambda x: (tf_load_image(x, resize_to=INPUT_SHAPE)))","metadata":{"execution":{"iopub.status.busy":"2021-08-05T22:28:51.275876Z","iopub.execute_input":"2021-08-05T22:28:51.276269Z","iopub.status.idle":"2021-08-05T22:28:53.273902Z","shell.execute_reply.started":"2021-08-05T22:28:51.276238Z","shell.execute_reply":"2021-08-05T22:28:53.272914Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"### COMPILING THE DATASET (NO SHUFFLING) ###\n\nAUTOTUNE = tf.data.AUTOTUNE\nbatch_size = 16 \n\n# we already mapped load_image\ntest_img_ds = test_img_ds.batch(batch_size).prefetch(AUTOTUNE)","metadata":{"execution":{"iopub.status.busy":"2021-08-05T22:28:57.586488Z","iopub.execute_input":"2021-08-05T22:28:57.586831Z","iopub.status.idle":"2021-08-05T22:28:57.593018Z","shell.execute_reply.started":"2021-08-05T22:28:57.586802Z","shell.execute_reply":"2021-08-05T22:28:57.592121Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## **Putting the Test Data through a Model**","metadata":{}},{"cell_type":"code","source":"###############################################\n##### access model from dataset uploaded  #####\n###############################################\n\n# get the sharing url of the model folder on gdrive (must be a ZIP file)\nmodel_path = '../input/model-2/epoch_15--val_loss_0.89--val_acc_0.66--val_AUC_0.87'","metadata":{"execution":{"iopub.status.busy":"2021-08-05T22:29:00.547719Z","iopub.execute_input":"2021-08-05T22:29:00.548142Z","iopub.status.idle":"2021-08-05T22:29:00.552515Z","shell.execute_reply.started":"2021-08-05T22:29:00.548105Z","shell.execute_reply":"2021-08-05T22:29:00.551354Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# load the model from the folder\nbest_model = tf.keras.models.load_model(model_path)","metadata":{"execution":{"iopub.status.busy":"2021-08-05T22:30:29.590368Z","iopub.execute_input":"2021-08-05T22:30:29.590712Z","iopub.status.idle":"2021-08-05T22:30:44.223441Z","shell.execute_reply.started":"2021-08-05T22:30:29.590679Z","shell.execute_reply":"2021-08-05T22:30:44.222559Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# get predictions on model on all 1263 images at once\nmodel_predict = best_model.predict(test_img_ds)","metadata":{"execution":{"iopub.status.busy":"2021-08-05T22:30:48.710932Z","iopub.execute_input":"2021-08-05T22:30:48.71136Z","iopub.status.idle":"2021-08-05T22:31:05.752751Z","shell.execute_reply.started":"2021-08-05T22:30:48.711319Z","shell.execute_reply":"2021-08-05T22:31:05.751677Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### **Making the Submission String(s)**","metadata":{}},{"cell_type":"code","source":"","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#########################################################\n##### Begin Making (Study-Level) Submission Strings #####\n#########################################################\n\nclass_dict = {0: 'atypical',\n              1: 'indeterminate',\n              2: 'negative',\n              3: 'typical'\n             }\n\ndef study_predictions_to_submission_format(model_predict, study_level_sample, class_dict, one_or_nothing=True):\n    \"\"\"\n    Use this function to get a pd.DataFrame that is the first half of the total submission dataframe,\n    more specifically, all the study level predictions. \n    \n    ARGS:\n    model_predict (np.ndarray)         : The outputs of your model on the test data. Should be (amt_test_exmpls, n_classes)\n    study_level_sample (pd.DataFrame)  : The study level section of the sample submission csv (the first 1214 lines)\n    class_dict (dict)                  : A dictionary mapping integer labels to word labels.\n    \n    KWARGS:\n    one_or_nothing (bool, dflt True)   : If you want confidence or just one or nothing.\n    \n    \"\"\"\n    # convert to pd.Series\n    model_predict = pd.DataFrame(model_predict)\n    \n    # turn logits into ints \n    int_predict = model_predict.apply(np.argmax, axis=1)\n    \n    # turn ints into words\n    word_predict = int_predict.apply(lambda x: class_dict[x])\n\n    # attatch the meaningless bounding box filler (just to keep same format with image-level)\n    p_strings = int_predict.apply(lambda x: class_dict[x] + str(' 1 0 0 1 1'))\n    \n    # now finally concatenate the class ids on the left (no shuffling so should be in same order)\n   \n    class_ids = study_level_sample['id']\n    \n    p_strings_with_ids = pd.concat([class_ids, p_strings], axis=1)\n    p_strings_with_ids.columns = ['id', 'PredictionString']\n    \n    return p_strings_with_ids\n    \n    \nstudy_submissions = study_predictions_to_submission_format(model_predict, studylvl_df, class_dict)","metadata":{"execution":{"iopub.status.busy":"2021-08-05T22:31:05.754804Z","iopub.execute_input":"2021-08-05T22:31:05.75518Z","iopub.status.idle":"2021-08-05T22:31:05.886143Z","shell.execute_reply.started":"2021-08-05T22:31:05.755139Z","shell.execute_reply":"2021-08-05T22:31:05.885183Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"print(study_submissions)","metadata":{"execution":{"iopub.status.busy":"2021-08-05T22:31:10.07186Z","iopub.execute_input":"2021-08-05T22:31:10.072183Z","iopub.status.idle":"2021-08-05T22:31:10.081353Z","shell.execute_reply.started":"2021-08-05T22:31:10.072155Z","shell.execute_reply":"2021-08-05T22:31:10.08012Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Start doing image level stuff\n","metadata":{}},{"cell_type":"code","source":"image_df = dhruv_master_df.set_index(['study_id']).apply(pd.Series.explode).reset_index()\nimage_df","metadata":{"execution":{"iopub.status.busy":"2021-08-05T22:31:13.366414Z","iopub.execute_input":"2021-08-05T22:31:13.366758Z","iopub.status.idle":"2021-08-05T22:31:13.397062Z","shell.execute_reply.started":"2021-08-05T22:31:13.366728Z","shell.execute_reply":"2021-08-05T22:31:13.396227Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"mod_study_sub = study_submissions.copy()\nmod_study_sub['study_id'] = mod_study_sub['id'].apply(lambda x: x.split('_')[0])\nmod_study_sub['class'] = mod_study_sub['PredictionString'].apply(lambda x: x.split(' ')[0])\nmod_study_sub.drop('PredictionString', axis=1, inplace=True)\nmod_study_sub.drop('id', axis=1, inplace=True)\nmod_study_sub","metadata":{"execution":{"iopub.status.busy":"2021-08-05T22:31:24.132469Z","iopub.execute_input":"2021-08-05T22:31:24.132817Z","iopub.status.idle":"2021-08-05T22:31:24.161832Z","shell.execute_reply.started":"2021-08-05T22:31:24.132786Z","shell.execute_reply":"2021-08-05T22:31:24.161092Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"image_df = image_df.merge(mod_study_sub,how='left',on='study_id')\nimage_df","metadata":{"execution":{"iopub.status.busy":"2021-08-05T22:31:27.570897Z","iopub.execute_input":"2021-08-05T22:31:27.571242Z","iopub.status.idle":"2021-08-05T22:31:27.605821Z","shell.execute_reply.started":"2021-08-05T22:31:27.571213Z","shell.execute_reply":"2021-08-05T22:31:27.604989Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"'''test_img_paths = list(image_df[\"image_paths\"])\n\n### DEFINE A FUNCITON TO LOAD IMAGES FROM PATH #######\n# more informatino on this functino can be found on accompanying colab notebooks\n\nINPUT_SHAPE = (512, 512, 3)\n\ndef tf_load_image(path, resize_to=INPUT_SHAPE):\n    img_bytes = tf.io.read_file(path)\n    img = tf.image.decode_png(img_bytes, channels=resize_to[-1])\n    img = tf.image.resize(img, resize_to[:-1])\n    img = tf.cast(img, tf.uint8)\n    return img\n\ntest_img_ds = tf.data.Dataset.from_tensor_slices(test_img_paths)\ntest_img_ds = test_img_ds.map(lambda x: (tf_load_image(x, resize_to=INPUT_SHAPE)))'''","metadata":{"execution":{"iopub.status.busy":"2021-08-05T19:37:16.287708Z","iopub.execute_input":"2021-08-05T19:37:16.288099Z","iopub.status.idle":"2021-08-05T19:37:16.376713Z","shell.execute_reply.started":"2021-08-05T19:37:16.288058Z","shell.execute_reply":"2021-08-05T19:37:16.375862Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"'''### COMPILING THE DATASET (NO SHUFFLING) ###\n\nAUTOTUNE = tf.data.AUTOTUNE\nbatch_size = 16 \n\n# we already mapped load_image\ntest_img_ds = test_img_ds.batch(batch_size).prefetch(AUTOTUNE)'''","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#Import the required libraries for Object detection infernece\nimport time\nimport tensorflow as tf\n#from object_detection.utils import label_map_util\n#from object_detection.utils import visualization_utils as viz_utils\nimport os\nimport cv2\nimport matplotlib.pyplot as plt\n#%matplotlib inline# setting min confidence threshold\n#MIN_CONF_THRESH=.6#Loading the exported model from saved_model directory\nPATH_TO_SAVED_MODEL =r'../input/tf-obj-api-effdetd0/TF_ObjDetAPI_EffDet_D0/saved_model'\nprint('Loading model...', end='')\nstart_time = time.time()# LOAD SAVED MODEL AND BUILD DETECTION FUNCTION\ndetect_fn = tf.saved_model.load(PATH_TO_SAVED_MODEL)\nend_time = time.time()\nelapsed_time = end_time - start_time\nprint('Done! Took {} seconds'.format(elapsed_time))# LOAD LABEL MAP DATA","metadata":{"execution":{"iopub.status.busy":"2021-08-09T19:42:19.827668Z","iopub.execute_input":"2021-08-09T19:42:19.827969Z","iopub.status.idle":"2021-08-09T19:42:52.269798Z","shell.execute_reply.started":"2021-08-09T19:42:19.827892Z","shell.execute_reply":"2021-08-09T19:42:52.268382Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def plot_image(image, boxes=None, size=(5,5), title=None, columns=4):\n    def plot_img(image, boxes=None, title=None):\n        if isinstance(image, str):\n            image_id = os.path.splitext(os.path.split(image)[1])[0]\n            df = df_image.loc[df_image['id'] == image_id + '_image']\n            boxes = string2boxes(df['label'].iloc[0]) if len(df) > 0 else None\n            image = read_dicom_image(image)\n        image = np.stack([image] * 3, axis=-1)\n        if boxes is not None:\n            for box in boxes:\n                image = cv2.rectangle(image, (int(box['x1']), int(box['y1'])), (int(box['x2']), int(box['y2'])), [0, 255, 0], 10)\n        plt.axis('on')\n        plt.imshow(image, cmap='gray')\n        if title is not None:\n            plt.title(title)\n\n    plt.figure(figsize=size)\n    if isinstance(image, list):\n        num = len(image)\n        columns = min(columns, num)\n        rows = math.ceil(num / columns)\n\n        for index, single_image in enumerate(image):\n            plt.subplot(rows, columns, index + 1)\n            plot_img(single_image, boxes=boxes, title=None if title is None else title[index])\n    else:\n        plot_img(image, boxes=boxes, title=title)\n    plt.show()","metadata":{"execution":{"iopub.status.busy":"2021-08-05T22:32:04.382299Z","iopub.execute_input":"2021-08-05T22:32:04.382707Z","iopub.status.idle":"2021-08-05T22:32:04.394353Z","shell.execute_reply.started":"2021-08-05T22:32:04.38267Z","shell.execute_reply":"2021-08-05T22:32:04.393363Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def get_prediction(IMAGE_PATH):\n    category_index = {1: {'id': 1, 'name': 'opacity'}}\n    \n\n\n\n    def load_image_into_numpy_array(path):\n        \"\"\"Load an image from file into a numpy array.\n        Puts image into numpy array of shape (height, width, channels), where channels=3 for RGB to feed into tensorflow graph.\n        Args:\n          path: the file path to the image\n        Returns:\n          uint8 numpy array with shape (img_height, img_width, 3)\n        \"\"\"\n        return np.array(cv2.cvtColor(cv2.imread(path), cv2.COLOR_BGR2RGB))\n    image_np = load_image_into_numpy_array(IMAGE_PATH)# Running the infernce on the image specified in the  image path\n    # The input needs to be a tensor, convert it using `tf.convert_to_tensor`.\n    input_tensor = tf.convert_to_tensor(image_np)\n    # The model expects a batch of images, so add an axis with `tf.newaxis`.\n    input_tensor = input_tensor[tf.newaxis, ...]\n    detections = detect_fn(input_tensor)\n\n    # All outputs are batches tensors.\n    # Convert to numpy arrays, and take index [0] to remove the batch dimension.\n    # We're only interested in the first num_detections.\n    num_detections = int(detections.pop('num_detections'))\n    detections = {key: value[0, :num_detections].numpy()\n                   for key, value in detections.items()}\n    detections['num_detections'] = num_detections# detection_classes should be ints.\n    detections['detection_classes'] = detections['detection_classes'].astype(np.int64)#print(detections['detection_classes'])\n    image_np_with_detections = image_np.copy()\n    return detections","metadata":{"execution":{"iopub.status.busy":"2021-08-05T22:32:07.541483Z","iopub.execute_input":"2021-08-05T22:32:07.541871Z","iopub.status.idle":"2021-08-05T22:32:07.549975Z","shell.execute_reply.started":"2021-08-05T22:32:07.541838Z","shell.execute_reply":"2021-08-05T22:32:07.549Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{"execution":{"iopub.status.busy":"2021-08-05T22:32:10.19129Z","iopub.execute_input":"2021-08-05T22:32:10.191872Z","iopub.status.idle":"2021-08-05T22:32:10.7206Z","shell.execute_reply.started":"2021-08-05T22:32:10.191832Z","shell.execute_reply":"2021-08-05T22:32:10.718103Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"image_df","metadata":{"execution":{"iopub.status.busy":"2021-08-05T22:32:21.222024Z","iopub.execute_input":"2021-08-05T22:32:21.222344Z","iopub.status.idle":"2021-08-05T22:32:21.240046Z","shell.execute_reply.started":"2021-08-05T22:32:21.222315Z","shell.execute_reply":"2021-08-05T22:32:21.23924Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"image_df.groupby('class').size()","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"list_img_id = list(image_df['image_id'])\nlist_image_paths = list(image_df['image_paths'])\nlist_og_image_sizes = list(image_df['og_image_sizes'])\nlist_class = list(image_df['class'])\n\n\n\n","metadata":{"execution":{"iopub.status.busy":"2021-08-05T22:32:24.211982Z","iopub.execute_input":"2021-08-05T22:32:24.212303Z","iopub.status.idle":"2021-08-05T22:32:24.218182Z","shell.execute_reply.started":"2021-08-05T22:32:24.212275Z","shell.execute_reply":"2021-08-05T22:32:24.217214Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"sub_df = pd.DataFrame(columns=['image_id','class','confidence','co-ordinates'])\nfor img_id,path,size,img_class in tqdm(zip(list_img_id,list_image_paths,list_og_image_sizes,list_class)):\n    if img_class == 'negative':\n        sub_df = sub_df.append({'image_id': img_id,'class':'none','confidence':1.0,'co-ordinates':str('0 0 1 1')}, ignore_index=True)\n    else:\n        detections = get_prediction(path)\n        if (detections['num_detections'] >0):\n            det_scores =  detections['detection_scores'][:3]\n            det_scores = [str(x) for x in det_scores]\n            #print(det_scores)\n            det_boxes = detections['detection_boxes'][:3]\n            #print(size)\n            #print(det_boxes[:2])\n            det_boxes = [[x[1],x[0],x[3],x[2]] for x in det_boxes]\n            #print(det_boxes[:2])\n            det_boxes = [[x[0]*size[1],x[1]*size[0],x[2]*size[1],x[3]*size[0]] for x in det_boxes]\n            #print(det_boxes[:2])\n            det_boxes = [[str(int(np.round(x[0]))),str(int(np.round(int(x[1])))),str(int(np.round(x[2]))),str(int(np.round(x[3])))] for x in det_boxes]\n            det_boxes = [\" \".join(y) for y in det_boxes ]\n            #print(det_boxes[:2])\n            classes = ['opacity' for x in det_scores]\n            #break\n            sub_df = sub_df.append({'image_id': img_id,'class':classes,'confidence':det_scores,'co-ordinates':det_boxes}, ignore_index=True)\n\n            \n            \n        else:\n            sub_df = sub_df.append({'image_id': img_id,'class':'none','confidence':str('1.0'),'co-ordinates':str('0 0 1 1')}, ignore_index=True)\n\n            \n        \n    \n\n","metadata":{"execution":{"iopub.status.busy":"2021-08-05T23:16:32.389967Z","iopub.execute_input":"2021-08-05T23:16:32.390282Z","iopub.status.idle":"2021-08-05T23:17:11.135232Z","shell.execute_reply.started":"2021-08-05T23:16:32.390255Z","shell.execute_reply":"2021-08-05T23:17:11.134387Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"sub_df","metadata":{"execution":{"iopub.status.busy":"2021-08-05T23:21:29.852558Z","iopub.execute_input":"2021-08-05T23:21:29.852908Z","iopub.status.idle":"2021-08-05T23:21:29.877477Z","shell.execute_reply.started":"2021-08-05T23:21:29.852879Z","shell.execute_reply":"2021-08-05T23:21:29.876448Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Convert  predictions in dataframe to submission csv format ","metadata":{}},{"cell_type":"code","source":"def make_image_prediction_string(row):\n    ans_string = \"\"\n    if type(row['class']) is not list:\n        row['class']=[row['class']]\n    \n    if type(row['confidence']) is not list:\n        row['confidence'] = [row['confidence']]\n        \n    if type(row['co-ordinates']) is not list:\n        row['co-ordinates'] = [row['co-ordinates']]\n   \n    for c,con,cord in zip(row['class'],row['confidence'],row['co-ordinates']):\n        clist = [str(c),str(con),str(cord)]\n        ans_string = ans_string +\" \"+\" \".join(clist)\n        \n        \n    return ans_string.strip()\n        \nsub_img_df  = sub_df.copy()\n#Id,PredictionString\nsub_img_df['Id'] = sub_img_df['image_id']\nsub_img_df['Id'] = sub_img_df.Id + \"_image\"\nsub_img_df.drop('image_id', axis=1, inplace=True)\nsub_img_df['PredictionString']  = sub_img_df.apply(lambda row: make_image_prediction_string(row),axis=1)\nsub_img_df = sub_img_df[['Id','PredictionString']]\nsub_img_df","metadata":{"execution":{"iopub.status.busy":"2021-08-05T23:36:36.727149Z","iopub.execute_input":"2021-08-05T23:36:36.727468Z","iopub.status.idle":"2021-08-05T23:36:36.829348Z","shell.execute_reply.started":"2021-08-05T23:36:36.727438Z","shell.execute_reply":"2021-08-05T23:36:36.828612Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# NOW we can simply just add the bottom 1263 rows directly from the sample submission \n# since we haven't done object detection yet.\nstudy_submissions.rename(columns={'id': 'Id'}, inplace=True)\n\n\nfinal_submission = pd.concat((study_submissions,sub_img_df ), axis=0)\n#final_submission = pd.concat((study_submissions,imagelvl_df ), axis=0)\n\nprint(\"FINAL SUBMISSION\\n=========================================\")\ndisplay(final_submission)\n\nprint(\"\\nSAVING AS CSV...\")\nfinal_submission.to_csv(\"submission.csv\", index=False)","metadata":{"execution":{"iopub.status.busy":"2021-08-05T23:39:21.230233Z","iopub.execute_input":"2021-08-05T23:39:21.23057Z","iopub.status.idle":"2021-08-05T23:39:21.284767Z","shell.execute_reply.started":"2021-08-05T23:39:21.230539Z","shell.execute_reply":"2021-08-05T23:39:21.283783Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"sub_img_df['class'] = sub_img_df.PredictionString.apply(lambda x: x.split(\" \")[0])\nsub_img_df\nsub_img_df.groupby('class').size()","metadata":{"execution":{"iopub.status.busy":"2021-08-05T23:44:29.714545Z","iopub.execute_input":"2021-08-05T23:44:29.714917Z","iopub.status.idle":"2021-08-05T23:44:29.73733Z","shell.execute_reply.started":"2021-08-05T23:44:29.714886Z","shell.execute_reply":"2021-08-05T23:44:29.736106Z"},"trusted":true},"execution_count":null,"outputs":[]}]}