{"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":"## Part 0: Pneumonia Exploratory Data Analysis","metadata":{}},{"cell_type":"markdown","source":"### Format of Data\n\n- <b><i>patientId_</i></b>- A patientId. Each patientId corresponds to a unique image.\n- <b><i>x_</i></b> - the upper-left x coordinate of the bounding box.\n- <b><i>y_</i></b> - the upper-left y coordinate of the bounding box.\n- <b><i>width_</i></b> - the width of the bounding box.\n- <b><i>height_</i></b> - the height of the bounding box.\n- <b><i>Target_</i></b> - the binary Target, indicating whether this sample has evidence of pneumonia. (1 = true, 0 = false)\n\n### Notes\n\n- A pneumonia opacity is a part of the lungs that looks darker on a radiograph and has a shape that indicates that pneumonia is (or may be) present.\n- Since the goal is to detect & then draw a bounding box on each pneumonia opacities (where each image can have 0 or many), and the training set is already classified:\n    - It can be analysed as a supervised learning statistical multilabel classification\n","metadata":{}},{"cell_type":"code","source":"# Imports\nimport cv2\nimport tqdm\nimport pydicom\nimport pylab as pl\nimport numpy as np \nimport pandas as pd \nimport seaborn as sns\nimport matplotlib.pylab as plt\n%matplotlib inline\n\nimport skimage\nfrom skimage import feature, filters\n\nimport os\nfrom os import listdir\nfrom os.path import isfile, join","metadata":{"execution":{"iopub.status.busy":"2021-07-31T13:12:22.552130Z","iopub.execute_input":"2021-07-31T13:12:22.552818Z","iopub.status.idle":"2021-07-31T13:12:24.826737Z","shell.execute_reply.started":"2021-07-31T13:12:22.552717Z","shell.execute_reply":"2021-07-31T13:12:24.825810Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"pathLabels = \"../input/rsna-pneumonia-detection-challenge/stage_2_train_labels.csv\"\nclassInfoPath = \"../input/rsna-pneumonia-detection-challenge/stage_2_detailed_class_info.csv\"\n\nlabels = pd.read_csv(pathLabels)\nclassInfo = pd.read_csv(classInfoPath)","metadata":{"execution":{"iopub.status.busy":"2021-07-31T13:12:49.059618Z","iopub.execute_input":"2021-07-31T13:12:49.059994Z","iopub.status.idle":"2021-07-31T13:12:49.209000Z","shell.execute_reply.started":"2021-07-31T13:12:49.059960Z","shell.execute_reply":"2021-07-31T13:12:49.208127Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Part 0.1: Merge ClassInfo & Labels","metadata":{}},{"cell_type":"code","source":"merged = pd.merge(left = classInfo, right = labels, how = 'left', on = 'patientId') # Merge\nmerged = merged.drop_duplicates() # Remove duplicates\n\nmerged.head()","metadata":{"execution":{"iopub.status.busy":"2021-07-31T13:13:10.776653Z","iopub.execute_input":"2021-07-31T13:13:10.777047Z","iopub.status.idle":"2021-07-31T13:13:10.873743Z","shell.execute_reply.started":"2021-07-31T13:13:10.777018Z","shell.execute_reply":"2021-07-31T13:13:10.872506Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"a = merged.loc[merged['class'] == \"No Lung Opacity / Not Normal\"]\n\na['Target'].value_counts()","metadata":{"execution":{"iopub.status.busy":"2021-07-31T13:13:32.112685Z","iopub.execute_input":"2021-07-31T13:13:32.113180Z","iopub.status.idle":"2021-07-31T13:13:32.129256Z","shell.execute_reply.started":"2021-07-31T13:13:32.113148Z","shell.execute_reply":"2021-07-31T13:13:32.128271Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# How many unique features?\nprint(f\"Unique features: \\n{merged.nunique()}\")","metadata":{"execution":{"iopub.status.busy":"2021-07-31T13:13:39.458409Z","iopub.execute_input":"2021-07-31T13:13:39.459046Z","iopub.status.idle":"2021-07-31T13:13:39.494056Z","shell.execute_reply.started":"2021-07-31T13:13:39.459007Z","shell.execute_reply":"2021-07-31T13:13:39.493296Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"neg, pos = merged[\"Target\"].value_counts()\n\nprint(f'How many people have pneumonia vs do not: \\n{merged[\"Target\"].value_counts()}\\n')\n\nprint(f'This is roughly {round(pos/(pos+neg)*100, 2)}% having pneumonia within this training data')","metadata":{"execution":{"iopub.status.busy":"2021-07-31T13:13:45.984730Z","iopub.execute_input":"2021-07-31T13:13:45.985079Z","iopub.status.idle":"2021-07-31T13:13:45.995345Z","shell.execute_reply.started":"2021-07-31T13:13:45.985043Z","shell.execute_reply":"2021-07-31T13:13:45.994114Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"##### We can see that over 20,000 people are classified as not having pneumonia, whereas around 10,000 people do\n\n##### This tells us that we have an imbalanced dataset\n\n##### To deal with this, we need to assign the class with less appeareances (i.e: having pneumonia) with a higher weight to even this imbalance out. We will do this by using a compute weight function, that we will use in our Modelling file","metadata":{}},{"cell_type":"code","source":"# See how many people with pneumonia vs non-pneumonia\nmerged['Target'].hist()","metadata":{"execution":{"iopub.status.busy":"2021-07-31T13:14:18.202405Z","iopub.execute_input":"2021-07-31T13:14:18.202822Z","iopub.status.idle":"2021-07-31T13:14:18.437408Z","shell.execute_reply.started":"2021-07-31T13:14:18.202785Z","shell.execute_reply":"2021-07-31T13:14:18.436633Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Look at the amounts in each of the different classes\nmerged['class'].hist();","metadata":{"execution":{"iopub.status.busy":"2021-07-31T13:14:22.972245Z","iopub.execute_input":"2021-07-31T13:14:22.972657Z","iopub.status.idle":"2021-07-31T13:14:23.257974Z","shell.execute_reply.started":"2021-07-31T13:14:22.972618Z","shell.execute_reply":"2021-07-31T13:14:23.257235Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"##### It seems that the amount is spread evenly between the 3 classes with roughly 2/3s being either classified as Normal or no lung opacity/not normal","metadata":{}},{"cell_type":"markdown","source":"## Part 0.2: Some Numerical Analysis","metadata":{}},{"cell_type":"markdown","source":"### Check out pneumonia classifying boxes","metadata":{}},{"cell_type":"code","source":"boxNums = merged.dropna()[['x', 'y', 'width', 'height']].copy() # Make a copy of just the boxes\n\n# Calculate x2 & y2 coordinates\nboxNums['x2'] = boxNums['x'] + boxNums['width']\nboxNums['y2'] = boxNums['y'] + boxNums['height']\n\n# Calculate x2 & y2 centres\nboxNums['xCentre'] = boxNums['x'] + boxNums['width']/2\nboxNums['yCentre'] = boxNums['y'] + boxNums['height']/2\n\n# Calculate area of the box\nboxNums['boxArea'] = boxNums['width'] * boxNums['height']","metadata":{"execution":{"iopub.status.busy":"2021-07-31T13:15:03.653414Z","iopub.execute_input":"2021-07-31T13:15:03.653998Z","iopub.status.idle":"2021-07-31T13:15:03.694326Z","shell.execute_reply.started":"2021-07-31T13:15:03.653961Z","shell.execute_reply":"2021-07-31T13:15:03.693343Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"boxNums.head(3)","metadata":{"execution":{"iopub.status.busy":"2021-07-31T13:15:08.940410Z","iopub.execute_input":"2021-07-31T13:15:08.940816Z","iopub.status.idle":"2021-07-31T13:15:08.961936Z","shell.execute_reply.started":"2021-07-31T13:15:08.940778Z","shell.execute_reply":"2021-07-31T13:15:08.960684Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Look at the correlations between x, y, x2, y2, width, height and the centres\n\npairs = [(boxNums['x'], boxNums['y']), (boxNums['x2'], boxNums['y2']), (boxNums['width'], boxNums['height']), \n         (boxNums['xCentre'], boxNums['yCentre'])]\n\naxis = [(0, 0), (0, 1), (1, 0), (1,1)]\n\nfig, axs = plt.subplots(2, 2, figsize=(10, 10))\n\nfor i in range(4):\n    axs[axis[i][0], axis[i][1]].hist2d(pairs[i][0], pairs[i][1], bins=30)\n\n# Set titles\naxs[0,0].set_title('X vs Y')\naxs[0,1].set_title('X2 vs Y2')\naxs[1,0].set_title('Width vs Height')\naxs[1,1].set_title('X Centre vs Y Centre')\n\nplt.show()   ","metadata":{"execution":{"iopub.status.busy":"2021-07-31T13:15:15.594940Z","iopub.execute_input":"2021-07-31T13:15:15.595350Z","iopub.status.idle":"2021-07-31T13:15:16.098645Z","shell.execute_reply.started":"2021-07-31T13:15:15.595313Z","shell.execute_reply":"2021-07-31T13:15:16.097682Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"##### Taking a look at the heatmap, we can see that the centres seems to have more density for x, x2 and y, y2","metadata":{}},{"cell_type":"code","source":"# Take a look at the distribution of box area\nboxNums['boxArea'].plot(kind='hist',\n                        bins=25,  \n                        figsize=(14,4), \n                        title='Area Distribution of boxes for a Positive target')","metadata":{"execution":{"iopub.status.busy":"2021-07-31T13:15:32.153192Z","iopub.execute_input":"2021-07-31T13:15:32.153587Z","iopub.status.idle":"2021-07-31T13:15:32.406735Z","shell.execute_reply.started":"2021-07-31T13:15:32.153537Z","shell.execute_reply":"2021-07-31T13:15:32.405692Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Part 0.3: Let's take a look at the Dicom Images ","metadata":{}},{"cell_type":"code","source":"# Get two patients (one who has pneumonia & one who doesnt)\npatient0 = merged['patientId'][0] # Doesn't have pneumonia\npatient1 = merged['patientId'][4] # Has pneumonia\n\npatients = [(patient0, \"Doesn't Have Pneumonia\"), (patient1, \"Has Pneumonia\")]\npatients","metadata":{"execution":{"iopub.status.busy":"2021-07-31T13:16:04.789709Z","iopub.execute_input":"2021-07-31T13:16:04.790160Z","iopub.status.idle":"2021-07-31T13:16:04.799638Z","shell.execute_reply.started":"2021-07-31T13:16:04.790128Z","shell.execute_reply":"2021-07-31T13:16:04.798487Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Plot the images side by side for visual comparison\nimgsPath = \"../input/rsna-pneumonia-detection-challenge/stage_2_train_images/\"\nfig, ax = plt.subplots(1, 2, figsize=(7,7))\n\nfor i in range(2):\n    \n    patientID, title = patients[i][0], patients[i][1] # Extract patient data\n    \n    dcmFile = f\"{imgsPath}{patientID}.dcm\" # Get path\n    dcmData = pydicom.read_file(dcmFile) # Read file\n    \n    img = dcmData.pixel_array # Get the pixel array\n    \n    ax[i].imshow(img, cmap=pl.cm.gist_gray) # Plot\n    ax[i].set_title(title) # Set title\n    ax[i].axis('off') # Remove axis","metadata":{"execution":{"iopub.status.busy":"2021-07-31T13:16:28.737197Z","iopub.execute_input":"2021-07-31T13:16:28.737756Z","iopub.status.idle":"2021-07-31T13:16:29.260173Z","shell.execute_reply.started":"2021-07-31T13:16:28.737694Z","shell.execute_reply":"2021-07-31T13:16:29.259363Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"##### We can see that the patient with pneumonia appears to have a much less opaque scan","metadata":{}},{"cell_type":"code","source":"p = merged.loc[merged['patientId'] == patient1]\np","metadata":{"execution":{"iopub.status.busy":"2021-07-31T13:16:36.557068Z","iopub.execute_input":"2021-07-31T13:16:36.557707Z","iopub.status.idle":"2021-07-31T13:16:36.578923Z","shell.execute_reply.started":"2021-07-31T13:16:36.557668Z","shell.execute_reply":"2021-07-31T13:16:36.578008Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"##### Important Note: A given patientId may have multiple boxes if more than one area of pneumonia is detected (see above).\n##### We can see that this particular patient (patient #5) has pneumonia, and has 2 entries, with 2 different boxes","metadata":{}},{"cell_type":"code","source":"# We want to create a Data parser to group a patients boxes with its image\ndef parseData(df):\n\n    newData = {}\n    \n    for n, row in df.iterrows():\n        \n        patientID = row['patientId'] # Initialise patient\n        \n        # If patient is not in the dict, add them\n        if patientID not in newData:\n            newData[patientID] = {\n                'dicom': f\"{imgsPath}{patientID}.dcm\",\n                'classifier': row['Target'],\n                'boxes': []}\n\n        # Add box if the patient has pneumonia\n        if newData[patientID]['classifier'] == 1:\n            newData[patientID]['boxes'].append([row['x'], row['y'], row['width'], row['height']])\n\n    return newData","metadata":{"execution":{"iopub.status.busy":"2021-07-31T13:17:19.029031Z","iopub.execute_input":"2021-07-31T13:17:19.029388Z","iopub.status.idle":"2021-07-31T13:17:19.035653Z","shell.execute_reply.started":"2021-07-31T13:17:19.029355Z","shell.execute_reply":"2021-07-31T13:17:19.034791Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"parsedData = parseData(merged)\n\n# Check patient 1 which we know has pneumonia\nparsedData[patient1]","metadata":{"execution":{"iopub.status.busy":"2021-07-31T13:17:25.298597Z","iopub.execute_input":"2021-07-31T13:17:25.299115Z","iopub.status.idle":"2021-07-31T13:17:28.353615Z","shell.execute_reply.started":"2021-07-31T13:17:25.299079Z","shell.execute_reply":"2021-07-31T13:17:28.352806Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"##### We can see that we have saved the file path, the classifier and the array of boxes for that person\n\n##### Now check someone we know that doesnt have pneumonia","metadata":{}},{"cell_type":"code","source":"parsedData[merged['patientId'][0]]","metadata":{"execution":{"iopub.status.busy":"2021-07-31T13:17:44.698423Z","iopub.execute_input":"2021-07-31T13:17:44.698857Z","iopub.status.idle":"2021-07-31T13:17:44.705372Z","shell.execute_reply.started":"2021-07-31T13:17:44.698820Z","shell.execute_reply":"2021-07-31T13:17:44.704286Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### Create a function that allows us to draw the boxes over the images","metadata":{}},{"cell_type":"code","source":"\"\"\"\nCredit for @peterchang77 for these 2 functions\n\"\"\"\n\n# This function will allow us to overlay a box\ndef overlayBox(im, box, rgb, stroke=1):\n\n    # --- Convert coordinates to integers\n    box = [int(b) for b in box]\n    \n    # --- Extract coordinates\n    x, y, width, height = box\n    y2 = y + height\n    x2 = x + width\n\n    im[y:y + stroke, x:x2] = rgb\n    im[y2:y2 + stroke, x:x2] = rgb\n    im[y:y2, x:x + stroke] = rgb\n    im[y:y2, x2:x2 + stroke] = rgb\n\n    return im\n\ndef drawBox(data):\n    \n    d = pydicom.read_file(data['dicom']) # Open and read the file\n    im = d.pixel_array\n\n    # Convert to 3 RGB\n    im = np.stack([im] * 3, axis=2)\n\n    # Add the boxes with random colours\n    for box in data['boxes']:\n        \n        rgb = np.floor(np.random.rand(3) * 256).astype('int') # Get rgb\n        \n        im = overlayBox(im=im, box=box, rgb=rgb, stroke=6) # Overlay the box\n\n    pl.imshow(im, cmap=pl.cm.gist_gray) # Show the image\n    pl.axis('off') # Remove axis","metadata":{"execution":{"iopub.status.busy":"2021-07-31T13:18:03.270107Z","iopub.execute_input":"2021-07-31T13:18:03.270503Z","iopub.status.idle":"2021-07-31T13:18:03.281335Z","shell.execute_reply.started":"2021-07-31T13:18:03.270459Z","shell.execute_reply":"2021-07-31T13:18:03.280207Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"drawBox(parsedData[patient1])","metadata":{"execution":{"iopub.status.busy":"2021-07-31T13:18:10.838331Z","iopub.execute_input":"2021-07-31T13:18:10.838730Z","iopub.status.idle":"2021-07-31T13:18:11.092930Z","shell.execute_reply.started":"2021-07-31T13:18:10.838681Z","shell.execute_reply":"2021-07-31T13:18:11.091941Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"##### We can see the dark opacities in the image were boxed, indicating the pnemonia","metadata":{}},{"cell_type":"markdown","source":"## Part 0.4: Viewing side-by-side of people having and not having Pneumonia","metadata":{}},{"cell_type":"markdown","source":"### Pneumonia = 0","metadata":{}},{"cell_type":"code","source":"# Get all patients with no pneumonia\npatients0 = [(row['patientId']) for n, row in merged.iterrows() if row['Target'] == 0]","metadata":{"execution":{"iopub.status.busy":"2021-07-31T13:18:55.446536Z","iopub.execute_input":"2021-07-31T13:18:55.446911Z","iopub.status.idle":"2021-07-31T13:18:58.065885Z","shell.execute_reply.started":"2021-07-31T13:18:55.446868Z","shell.execute_reply":"2021-07-31T13:18:58.065037Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"fig = plt.figure(figsize=(20, 10))\n \ncolumns = 6\nrows = 4\n\nfor i in range(1, columns*rows +1):\n    \n    fig.add_subplot(rows, columns, i) # Add the subplot\n    drawBox(parsedData[patients0[i]]) # Draw the box","metadata":{"execution":{"iopub.status.busy":"2021-07-31T13:19:01.752508Z","iopub.execute_input":"2021-07-31T13:19:01.753053Z","iopub.status.idle":"2021-07-31T13:19:07.282619Z","shell.execute_reply.started":"2021-07-31T13:19:01.753019Z","shell.execute_reply":"2021-07-31T13:19:07.281421Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### Pneumonia = 1","metadata":{}},{"cell_type":"code","source":"# Get all patients with pneumonia\npatients1 = [(row['patientId']) for n, row in merged.iterrows() if row['Target'] == 1]","metadata":{"execution":{"iopub.status.busy":"2021-07-31T13:19:19.842613Z","iopub.execute_input":"2021-07-31T13:19:19.842975Z","iopub.status.idle":"2021-07-31T13:19:22.376007Z","shell.execute_reply.started":"2021-07-31T13:19:19.842943Z","shell.execute_reply":"2021-07-31T13:19:22.375123Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"fig = plt.figure(figsize=(20, 10))\n \ncolumns = 6\nrows = 4\n\nfor i in range(1, columns*rows +1):\n    \n    fig.add_subplot(rows, columns, i) # Add the subplot\n    drawBox(parsedData[patients1[i]]) # Draw the box","metadata":{"execution":{"iopub.status.busy":"2021-07-31T13:19:28.502368Z","iopub.execute_input":"2021-07-31T13:19:28.502742Z","iopub.status.idle":"2021-07-31T13:19:33.669371Z","shell.execute_reply.started":"2021-07-31T13:19:28.502712Z","shell.execute_reply":"2021-07-31T13:19:33.668292Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Part 0.5: Some Feature Analysis for Standard Models","metadata":{}},{"cell_type":"code","source":"def readImage(pId):\n        \n    patient = parsedData[pId]\n    path = patient['dicom']\n\n    img = pydicom.read_file(path).pixel_array # Read & Convert to pixels\n    \n    return img","metadata":{"execution":{"iopub.status.busy":"2021-07-31T13:20:04.044407Z","iopub.execute_input":"2021-07-31T13:20:04.044769Z","iopub.status.idle":"2021-07-31T13:20:04.049165Z","shell.execute_reply.started":"2021-07-31T13:20:04.044740Z","shell.execute_reply":"2021-07-31T13:20:04.048424Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"noPne = readImage(patients0[1])\npne = readImage(patients1[1])","metadata":{"execution":{"iopub.status.busy":"2021-07-31T13:20:09.806907Z","iopub.execute_input":"2021-07-31T13:20:09.807280Z","iopub.status.idle":"2021-07-31T13:20:09.834009Z","shell.execute_reply.started":"2021-07-31T13:20:09.807251Z","shell.execute_reply":"2021-07-31T13:20:09.833125Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def printTwoImgs(img1, img2, title1, title2):\n    \n    fig, ax = plt.subplots(1, 2, figsize=(12,12))\n\n    ax[0].imshow(img1, cmap=\"gray\")\n    ax[1].imshow(img2, cmap=\"gray\")\n    \n    ax[0].set_title(title1)\n    ax[1].set_title(title2)\n    \n    ax[0].axis('off')\n    ax[1].axis('off')","metadata":{"execution":{"iopub.status.busy":"2021-07-31T13:20:49.076526Z","iopub.execute_input":"2021-07-31T13:20:49.077082Z","iopub.status.idle":"2021-07-31T13:20:49.082882Z","shell.execute_reply.started":"2021-07-31T13:20:49.077036Z","shell.execute_reply":"2021-07-31T13:20:49.082016Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"printTwoImgs(noPne, pne, \"No Pneumonia - Normal Image\", \"Pneumonia - Normal Image\")","metadata":{"execution":{"iopub.status.busy":"2021-07-31T13:20:50.983362Z","iopub.execute_input":"2021-07-31T13:20:50.983758Z","iopub.status.idle":"2021-07-31T13:20:51.513472Z","shell.execute_reply.started":"2021-07-31T13:20:50.983701Z","shell.execute_reply":"2021-07-31T13:20:51.512317Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### Hist Equalisation","metadata":{}},{"cell_type":"code","source":"equ1 = cv2.equalizeHist(noPne)\nequ2 = cv2.equalizeHist(pne)\n\nprintTwoImgs(equ1, equ2, \"No Pneumonia\", \"Pneumonia\") # Print images","metadata":{"execution":{"iopub.status.busy":"2021-07-31T13:21:28.258934Z","iopub.execute_input":"2021-07-31T13:21:28.259302Z","iopub.status.idle":"2021-07-31T13:21:28.796093Z","shell.execute_reply.started":"2021-07-31T13:21:28.259272Z","shell.execute_reply":"2021-07-31T13:21:28.795002Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### Image Sharpening","metadata":{}},{"cell_type":"code","source":"hpf_kernel = np.full((3, 3), -1)\nhpf_kernel[1,1] = 9\n\nimHP = cv2.filter2D(equ1, -1, hpf_kernel)\nimUS = skimage.filters.unsharp_mask(equ1) # use unsharpen mask filter\n\nimHP2 = cv2.filter2D(equ2, -1, hpf_kernel)\nimUS2 = skimage.filters.unsharp_mask(equ2) # use unsharpen mask filter\n\nprintTwoImgs(imHP, imHP2, \"No Pneu - High Pass\", \"Pneu - High Pass\") # Print images\n\nprintTwoImgs(imUS, imUS2, \"No Pneu - Unsharpen Mask\", \"Pneu - Unsharpen Mask\") # Print images","metadata":{"execution":{"iopub.status.busy":"2021-07-31T13:21:46.855720Z","iopub.execute_input":"2021-07-31T13:21:46.856085Z","iopub.status.idle":"2021-07-31T13:21:48.007157Z","shell.execute_reply.started":"2021-07-31T13:21:46.856053Z","shell.execute_reply":"2021-07-31T13:21:48.006009Z"},"trusted":true},"execution_count":null,"outputs":[]}]}