{"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":"# Image Preprocessing\n\nRefs: \n- https://www.kaggle.com/code/masatakaitakura/rsna-2022-for-beginner-detect-breast-area/notebook\n- https://www.kaggle.com/code/theoviel/dicom-resized-png-jpg\n","metadata":{}},{"cell_type":"code","source":"%load_ext autoreload\n%autoreload 2","metadata":{"execution":{"iopub.status.busy":"2023-01-16T10:59:00.908959Z","iopub.execute_input":"2023-01-16T10:59:00.909552Z","iopub.status.idle":"2023-01-16T10:59:00.98181Z","shell.execute_reply.started":"2023-01-16T10:59:00.909429Z","shell.execute_reply":"2023-01-16T10:59:00.980611Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Import library\n\n## Basic ##\n%matplotlib inline\n# Needed to autoreload after installing pylibjpeg plugins\n#%load_ext autoreload\nimport pandas as pd\nimport numpy as np\nimport matplotlib.pyplot as plt\nimport os\nimport cv2\nimport glob\nfrom tqdm.notebook import tqdm\n\n## dicom file relevant\n!pip install pylibjpeg pylibjpeg-libjpeg pylibjpeg-openjpeg\n\nimport pylibjpeg\nimport pydicom\nfrom joblib import Parallel, delayed\n\n\n## Setting for matplotlib\nplt.rcParams['font.size'] = 14\nplt.rcParams['figure.figsize'] = (6,6)\nplt.rcParams['axes.grid'] = True","metadata":{"execution":{"iopub.status.busy":"2023-01-16T10:59:00.984189Z","iopub.execute_input":"2023-01-16T10:59:00.985044Z","iopub.status.idle":"2023-01-16T10:59:15.180671Z","shell.execute_reply.started":"2023-01-16T10:59:00.985008Z","shell.execute_reply":"2023-01-16T10:59:15.17961Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Read DICOM file\ndef get_dicom_image(fname):\n    size=512\n\n    # obtain ids\n    patient_id = fname.split('/')[-2]\n    image_id = fname.split('/')[-1][:-4]\n\n    # image file\n    dicom = pydicom.dcmread(fname)\n    try:\n        img = dicom.pixel_array\n    except RuntimeError as e:\n        print(f\"Image not supported {fname}\")\n        print(e)\n        return None\n    # normalize image\n    img = (img - img.min()) / (img.max() - img.min())\n    if dicom.PhotometricInterpretation == \"MONOCHROME1\":\n        img = 1 - img\n    img = cv2.resize(img, (size, size))\n    return img","metadata":{"execution":{"iopub.status.busy":"2023-01-16T10:59:15.182501Z","iopub.execute_input":"2023-01-16T10:59:15.182874Z","iopub.status.idle":"2023-01-16T10:59:15.220314Z","shell.execute_reply.started":"2023-01-16T10:59:15.182834Z","shell.execute_reply":"2023-01-16T10:59:15.219416Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"!rm -rf \"png_256/\"","metadata":{"execution":{"iopub.status.busy":"2023-01-16T10:59:15.224131Z","iopub.execute_input":"2023-01-16T10:59:15.22445Z","iopub.status.idle":"2023-01-16T10:59:16.319799Z","shell.execute_reply.started":"2023-01-16T10:59:15.224423Z","shell.execute_reply":"2023-01-16T10:59:16.31841Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_images = glob.glob(\"/kaggle/input/rsna-breast-cancer-detection/train_images/*/*.dcm\")\n\nlen(train_images)  # 54706","metadata":{"execution":{"iopub.status.busy":"2023-01-16T10:59:16.325215Z","iopub.execute_input":"2023-01-16T10:59:16.32599Z","iopub.status.idle":"2023-01-16T11:00:35.35305Z","shell.execute_reply.started":"2023-01-16T10:59:16.325946Z","shell.execute_reply":"2023-01-16T11:00:35.352164Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"SAVE_FOLDER = \"png_256/\"\nSIZE = 256\nEXTENSION = \"png\"\n\nos.makedirs(SAVE_FOLDER, exist_ok=True)","metadata":{"execution":{"iopub.status.busy":"2023-01-16T11:00:35.354646Z","iopub.execute_input":"2023-01-16T11:00:35.354999Z","iopub.status.idle":"2023-01-16T11:00:35.385866Z","shell.execute_reply.started":"2023-01-16T11:00:35.354965Z","shell.execute_reply":"2023-01-16T11:00:35.384935Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# create and save png file\nthreshold = 0.5\ndef process(f, size=512, save_folder=\"png/\", extension=\"png\"):\n    patient = f.split('/')[-2]\n    image = f.split('/')[-1][:-4]\n    \n    out_file = save_folder + f\"{patient}_{image}.{extension}\"\n    if os.path.isfile(out_file):\n        print(\"img already exists\")\n        return None\n\n    dicom = pydicom.dcmread(f)\n    try:\n        img = dicom.pixel_array\n    except RuntimeError as e:\n        print(f\"Error on {f}:\")\n        print(e)\n        return None\n\n    img = (img - img.min()) / (img.max() - img.min())\n\n    if dicom.PhotometricInterpretation == \"MONOCHROME1\":\n        img = 1 - img\n    \n    # show rectangle\n    i = 0\n    img = cv2.resize(img, (size, size))\n    img = (img * 255).astype(np.uint8)\n    retval, labels, stats, centroids = cv2.connectedComponentsWithStats(image=(img > threshold).astype(np.uint8)[:, :], connectivity=8, ltype=cv2.CV_32S)\n    datas = max([(x, y, width, height, area) for x, y, width, height, area in stats[1:]],key= lambda x: x[-1] )\n\n    x, y, width, height, area = datas\n    bounds = 0\n#    cv2.rectangle(img,\n#                  pt1=(x,y),\n#                  pt2=(x+width+bounds,y+height+bounds),\n#                  color=(255,0,0),\n#                  thickness=5)\n#            print([y,y+height, x,x+width])\n    img = img[y:y+height+bounds, x:x+width+bounds]\n    cv2.imwrite(out_file, img)","metadata":{"execution":{"iopub.status.busy":"2023-01-16T11:00:35.387528Z","iopub.execute_input":"2023-01-16T11:00:35.387919Z","iopub.status.idle":"2023-01-16T11:00:35.430484Z","shell.execute_reply.started":"2023-01-16T11:00:35.387882Z","shell.execute_reply":"2023-01-16T11:00:35.429349Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"_ = Parallel(n_jobs=4)(\n    delayed(process)(uid, size=SIZE, save_folder=SAVE_FOLDER, extension=EXTENSION)\n    for uid in tqdm(train_images[:800])\n#    for uid in tqdm(train_images[:20])\n)","metadata":{"execution":{"iopub.status.busy":"2023-01-16T11:00:35.43211Z","iopub.execute_input":"2023-01-16T11:00:35.432534Z","iopub.status.idle":"2023-01-16T11:07:29.096686Z","shell.execute_reply.started":"2023-01-16T11:00:35.432476Z","shell.execute_reply":"2023-01-16T11:07:29.095539Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"png_images = glob.glob(f'/kaggle/working/{SAVE_FOLDER}/*.{EXTENSION}')\n\nlen(png_images)","metadata":{"execution":{"iopub.status.busy":"2023-01-16T11:07:29.098482Z","iopub.execute_input":"2023-01-16T11:07:29.099207Z","iopub.status.idle":"2023-01-16T11:07:29.142386Z","shell.execute_reply.started":"2023-01-16T11:07:29.099161Z","shell.execute_reply":"2023-01-16T11:07:29.141396Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def display_cropped(png_images):\n    # Plot result\n    col = 2\n    row = len(png_images)\n    fig, axes = plt.subplots(row, col, figsize=(20,20))\n\n    for idx, image in enumerate(png_images):\n        frame = cv2.imread(image)\n\n        img_data = image.split(\"/\")[-1].split(\"_\")\n        image_id = img_data[1].replace(\".png\", \"\")\n        patient_id = img_data[0].split(\"/\")[-1]\n        i = idx // col\n        i = idx\n        j = idx % col\n        j = 0\n        axes[i, j].imshow(frame)\n        original_img = get_dicom_image(f\"/kaggle/input/rsna-breast-cancer-detection/train_images/{patient_id}/{image_id}.dcm\")\n        if original_img is not None:\n            axes[i, 1].imshow(original_img)\n\n    plt.subplots_adjust(wspace=0.2, hspace=0.5)\n    plt.show()","metadata":{"execution":{"iopub.status.busy":"2023-01-16T11:07:29.146337Z","iopub.execute_input":"2023-01-16T11:07:29.146631Z","iopub.status.idle":"2023-01-16T11:07:29.180045Z","shell.execute_reply.started":"2023-01-16T11:07:29.146603Z","shell.execute_reply":"2023-01-16T11:07:29.179213Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from random import choices\ndisplay_cropped(choices(png_images, k=3))","metadata":{"execution":{"iopub.status.busy":"2023-01-16T11:07:29.18149Z","iopub.execute_input":"2023-01-16T11:07:29.182277Z","iopub.status.idle":"2023-01-16T11:07:30.790719Z","shell.execute_reply.started":"2023-01-16T11:07:29.182233Z","shell.execute_reply":"2023-01-16T11:07:30.787453Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]}]}