text_plain_output_1.png
from PIL import Image

import matplotlib.pyplot as plt

import numpy as np

import os

import pandas as pd

import seaborn as sns

data_path = '/kaggle/input/covidx9a/'
images_path = '/kaggle/input/covidx-cxr2/train/'
data_file = 'train_COVIDx9A.txt'
train = pd.read_csv(os.path.join(data_path, data_file), header=None, sep=' ')
train.columns = ['patient id', 'filename', 'class', 'data source']

data_classes = train['class'].unique()
df_summary_count = pd.DataFrame()
for dataset in ['cohen', 'fig1', 'actmed', 'sirm', 'ricord', 'rsna', 'stonybrook', 'bimcv', 'rnsa']:
    num_negative = train.loc[(train['data source'] == dataset) & (train['class'] == data_classes[0]), 'filename'].count()
    if len(data_classes) == 2:
        num_positive = train.loc[(train['data source'] == dataset) & (train['class'] == data_classes[1]), 'filename'].count()
        df_new = pd.DataFrame({'Dataset': [dataset], 'Covid': [num_positive], 'Negative': [num_negative]})
    elif len(data_classes) == 3:
        num_pneumonia = train.loc[(train['data source'] == dataset) & (train['class'] == data_classes[1]), 'filename'].count()
        num_positive = train.loc[(train['data source'] == dataset) & (train['class'] == data_classes[2]), 'filename'].count()
        df_new = pd.DataFrame({'Dataset': [dataset], 'Covid': [num_positive], 'Pneumonia': [num_pneumonia], 'Negative': [num_negative]})
    df_summary_count = pd.concat([df_summary_count, df_new])

patient_distribution = train.groupby(['patient id', 'data source', 'class']).count().reset_index()
patient_distribution.rename(columns={'filename': 'num_patients'}, inplace=True)
num_patients_bydata = patient_distribution[['data source', 'num_patients']].groupby(['data source']).count()
num_patients_byclass = patient_distribution[['class', 'num_patients']].groupby(['class']).count()

def crop_resize_image(gray_img, final_size=224):
    """ Set the new dimensions so the cropped image is a square
    """
    width, height = gray_img.size
    diff = abs(width - height)
    left, right, top, bottom = (0, 0, 0, 0)
    if diff % 2 == 0:
        if width > height:
            bottom = height
            left = diff / 2
            right = width - left
        elif height > width:
            top = diff / 2
            bottom = height - top
            right = width
    elif width > height:
        bottom = height
        left = diff / 2 + 0.5
        right = width - left + 1
    elif height > width:
        top = diff / 2 + 0.5
        bottom = height - top + 1
        right = width
    img_cropped = gray_img.crop((left, top, right, bottom))
    img_final = img_cropped.resize((final_size, final_size))
    return img_final

### Look at a few images to explore:
#    a) what do the scans look like for each class?
#    b) what is the image resolution?
#    c) is there anything noticeable across classes / images?

# Kaggle dataset
print('Images are saved at:', images_path)

fig, axs = plt.subplots(3, 3, figsize = (18,14))

for i in range(3):
    for j in range(3):
        if j==0:
            file_name, class_label = train[train['class']==data_classes[0]].iloc[i,[1,2]]
        elif j==1:
            file_name, class_label = train[train['class']==data_classes[1]].iloc[i,[1,2]]
        elif j==2 and len(data_classes)==3:
            file_name, class_label = train[train['class']==data_classes[2]].iloc[i,[1,2]]
        else:
            print('Out of bounds')
            
        image_file = os.path.join(images_path, file_name)

        img = Image.open(image_file)
        print('Original:', (3*i+j), np.asarray(img).shape)
        # Greyscale convert
        img = img.convert('L')
        
        axs[i,j].set_title(f'Class: {class_label} - Image Size: {np.asarray(img).shape}')
        axs[i,j].axis('off')
        axs[i,j].imshow(img, cmap = 'gray')

plt.show()

final_size = 224
fig, axs = plt.subplots(3, 3, figsize=(18, 14))
for i in range(3):
    for j in range(3):
        if j == 0:
            file_name, class_label = train[train['class'] == data_classes[0]].iloc[i, [1, 2]]
        elif j == 1:
            file_name, class_label = train[train['class'] == data_classes[1]].iloc[i, [1, 2]]
        elif j == 2 and len(data_classes) == 3:
            file_name, class_label = train[train['class'] == data_classes[2]].iloc[i, [1, 2]]
        else:
            print('Out of bounds')
        image_file = os.path.join(images_path, file_name)
        img = Image.open(image_file)
        img = img.convert('L')
        img = crop_resize_image(img, final_size=224)
        axs[i, j].set_title(f'Class: {class_label} - Image Size: {np.asarray(img_final).shape}')
        axs[i, j].axis('off')
        axs[i, j].imshow(img_final, cmap='gray')
plt.show()