{"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 numpy as np\nimport pydicom\nimport matplotlib.pyplot as plt\nimport cv2\nfrom pydicom.pixel_data_handlers import apply_voi_lut","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","execution":{"iopub.status.busy":"2022-11-30T15:38:05.13555Z","iopub.execute_input":"2022-11-30T15:38:05.135988Z","iopub.status.idle":"2022-11-30T15:38:05.14304Z","shell.execute_reply.started":"2022-11-30T15:38:05.135944Z","shell.execute_reply":"2022-11-30T15:38:05.141654Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"<div class='alert alert-info' style='text-align:center'><h1>Mammography Image Padding</h1>\n- yet another DICOM processing notebook -</div>\n\n#### Left/Right pad-to-square.\n- A quick method to determine which side of a mammo image to pad to make the image square.\n- We'll apply VOI LUT to make the images appear as they would to a human reader.","metadata":{}},{"cell_type":"code","source":"# This function is for extracting pixels from DICOM files.\n#\ndef get_pixels(dcm_file):\n    im = pydicom.dcmread(dcm_file)\n    \n    data = im.pixel_array\n    \n    data = apply_voi_lut(data, im)\n    \n    if im.PhotometricInterpretation == \"MONOCHROME1\":\n        data = np.amax(data) - data\n    else:\n        data = data - np.min(data)\n        \n    if np.max(data) != 0:\n        data = data / np.max(data)\n    data=(data * 255).astype(np.uint8)\n    \n    return data","metadata":{"execution":{"iopub.status.busy":"2022-11-30T15:38:05.145453Z","iopub.execute_input":"2022-11-30T15:38:05.145964Z","iopub.status.idle":"2022-11-30T15:38:05.157347Z","shell.execute_reply.started":"2022-11-30T15:38:05.145927Z","shell.execute_reply":"2022-11-30T15:38:05.155864Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Determine the mean pixel value of the first and last column of pixels.\n# The darker side (where the breast is NOT), will have a much lower mean value.\n\ndef pad_pixels(p):\n    \n    mean_left = p[:,0].mean()\n    mean_right = p[:,p.shape[1]-1].mean()\n    border_r = 0\n    border_l = 0\n\n    if p.shape[0] > p.shape[1]:\n        border_size = p.shape[0] - p.shape[1]\n\n        if mean_left > mean_right:\n            border_r = border_size\n        else:\n            border_l = border_size\n            \n        pixels = cv2.copyMakeBorder(p, 0, 0, border_l, border_r, borderType=cv2.BORDER_CONSTANT, value=[0,0,0])\n        \n        return pixels","metadata":{"execution":{"iopub.status.busy":"2022-11-30T15:38:05.158869Z","iopub.execute_input":"2022-11-30T15:38:05.159733Z","iopub.status.idle":"2022-11-30T15:38:05.170438Z","shell.execute_reply.started":"2022-11-30T15:38:05.159698Z","shell.execute_reply":"2022-11-30T15:38:05.168921Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### Grab a random image\n- You'll need to install GDCM and pylibjpeg to open some of JPG compressed mammo images in this dataset.","metadata":{}},{"cell_type":"code","source":"# Open an image and get pixels \npixels = get_pixels(\"/kaggle/input/rsna-breast-cancer-detection/train_images/10152/1280087654.dcm\")\n\n# Pad the original pixels to make them square\npixels_padded = pad_pixels(pixels)","metadata":{"execution":{"iopub.status.busy":"2022-11-30T15:38:05.171996Z","iopub.execute_input":"2022-11-30T15:38:05.172631Z","iopub.status.idle":"2022-11-30T15:38:07.041912Z","shell.execute_reply.started":"2022-11-30T15:38:05.172596Z","shell.execute_reply":"2022-11-30T15:38:07.041052Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Plot the images\n# The padding should be on the correct side of the image\n#\nfig, axes = plt.subplots(nrows=1, ncols=2,sharex=False, sharey=True, figsize=(12, 6))\nax = axes.ravel()\nax[0].set_title(f'Original: {pixels.shape[0]} x {pixels.shape[1]}')\nax[0].imshow(pixels, cmap='gray');\nax[1].set_title(f'Padded: {pixels_padded.shape[0]} x {pixels_padded.shape[1]}')\nax[1].imshow(pixels_padded, cmap='gray');","metadata":{"execution":{"iopub.status.busy":"2022-11-30T15:38:07.044079Z","iopub.execute_input":"2022-11-30T15:38:07.044698Z","iopub.status.idle":"2022-11-30T15:38:12.008739Z","shell.execute_reply.started":"2022-11-30T15:38:07.044662Z","shell.execute_reply":"2022-11-30T15:38:12.007542Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### Let's do one on the opposite side","metadata":{}},{"cell_type":"code","source":"# Open an image and get pixels \npixels = get_pixels(\"/kaggle/input/rsna-breast-cancer-detection/train_images/10152/1774592645.dcm\")\n\n# Pad the original pixels to make them square\npixels_padded = pad_pixels(pixels)","metadata":{"execution":{"iopub.status.busy":"2022-11-30T15:38:12.010228Z","iopub.execute_input":"2022-11-30T15:38:12.011257Z","iopub.status.idle":"2022-11-30T15:38:13.931631Z","shell.execute_reply.started":"2022-11-30T15:38:12.011207Z","shell.execute_reply":"2022-11-30T15:38:13.930416Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Plot the images\nfig, axes = plt.subplots(nrows=1, ncols=2,sharex=False, sharey=True, figsize=(12, 6))\nax = axes.ravel()\nax[0].set_title(f'Original: {pixels.shape[0]} x {pixels.shape[1]}')\nax[0].imshow(pixels, cmap='gray');\nax[1].set_title(f'Padded: {pixels_padded.shape[0]} x {pixels_padded.shape[1]}')\nax[1].imshow(pixels_padded, cmap='gray');","metadata":{"execution":{"iopub.status.busy":"2022-11-30T15:39:07.059458Z","iopub.execute_input":"2022-11-30T15:39:07.059876Z","iopub.status.idle":"2022-11-30T15:39:12.290347Z","shell.execute_reply.started":"2022-11-30T15:39:07.05983Z","shell.execute_reply":"2022-11-30T15:39:12.289184Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### Conclusion\n- This is a simple method to add padding to the empty side of a non-square mammogram image.\n- Allows for exporting of images as square without distorting anatomy.\n- ** It only pads the width, it does not pad height, or top/bottom.","metadata":{}}]}