{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"name":"python","version":"3.7.9","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"},"kaggle":{"accelerator":"none","dataSources":[{"sourceType":"competition","sourceId":24800,"datasetId":1042002,"databundleVersionId":1831594}],"dockerImageVersionId":30055,"isInternetEnabled":true,"language":"python","sourceType":"notebook","isGpuEnabled":false}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"markdown","source":"# VinBigData Chest X-ray Abnormalities Detection\nAutomatically localize and classify thoracic abnormalities from chest radiographs\n\n#### The aim of this notebook is to explore the histogram equalization technique and it's variant.","metadata":{}},{"cell_type":"markdown","source":"## Import libraries","metadata":{}},{"cell_type":"code","source":"!pip install tensorflow_io","metadata":{"_kg_hide-input":true,"_kg_hide-output":true,"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import os\nimport pandas as pd\nimport numpy as np\nimport cv2\nimport matplotlib.pyplot as plt\nimport pydicom\nimport torch\nimport torchvision.transforms as transforms","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","execution":{"iopub.status.busy":"2024-01-18T08:45:51.205189Z","iopub.execute_input":"2024-01-18T08:45:51.205944Z","iopub.status.idle":"2024-01-18T08:45:53.451266Z","shell.execute_reply.started":"2024-01-18T08:45:51.205802Z","shell.execute_reply":"2024-01-18T08:45:53.450172Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Read DICOM images","metadata":{}},{"cell_type":"code","source":"def read_dicom(path):\n    # Read the DICOM file\n    dicom = pydicom.dcmread(path)\n    image = dicom.pixel_array\n\n    # Convert to a numpy array of type float32\n    image = image.astype(np.float32)\n\n    # Convert to a PyTorch tensor\n    image = torch.from_numpy(image)\n\n    # Reshape if it's a single channel image\n    if len(image.shape) == 2:\n        image = image.unsqueeze(0)  # Add a channel dimension\n\n    # Resize the image to 500x500\n    resize_transform = transforms.Resize((500, 500))\n    image = resize_transform(image)\n\n    # Normalize the image\n    image = image - torch.min(image)\n    image = image / torch.max(image)\n    image = image * 255.0\n\n    # Convert to uint8\n    image = image.to(torch.uint8)\n    # Change shape from (1, 500, 500) to (500, 500, 1)\n    image = image.squeeze(0).unsqueeze(2)\n    return image","metadata":{"execution":{"iopub.status.busy":"2024-01-18T08:53:16.176342Z","iopub.execute_input":"2024-01-18T08:53:16.176761Z","iopub.status.idle":"2024-01-18T08:53:16.185584Z","shell.execute_reply.started":"2024-01-18T08:53:16.17672Z","shell.execute_reply":"2024-01-18T08:53:16.184458Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Visualization","metadata":{}},{"cell_type":"markdown","source":"### Original","metadata":{}},{"cell_type":"code","source":"fpath = \"../input/vinbigdata-chest-xray-abnormalities-detection/train/000434271f63a053c4128a0ba6352c7f.dicom\"\nimage = read_dicom(fpath)\n\nplt.figure(figsize = (18, 4))\n\nplt.subplot(1, 2, 1)\nplt.axis(\"off\")\nplt.title(\"Original\")\nplt.imshow(image, cmap = \"gray\");\n\nplt.subplot(1, 2, 2)\nhist, bins = np.histogram(image.numpy().flatten(), 256, [0, 256])\ncdf = hist.cumsum()\ncdf_normalized = cdf * float(hist.max()) / cdf.max()\nplt.plot(cdf_normalized, color = 'b')\n\nplt.hist(image.numpy().flatten(), 256, [0, 256], color = 'r')\nplt.xlim([0, 256])\nplt.legend(('cdf', 'histogram'), loc = 'upper left')\nplt.title(\"Original\")\nplt.show();","metadata":{"execution":{"iopub.status.busy":"2024-01-18T08:53:16.840554Z","iopub.execute_input":"2024-01-18T08:53:16.841525Z","iopub.status.idle":"2024-01-18T08:53:17.739296Z","shell.execute_reply.started":"2024-01-18T08:53:16.84146Z","shell.execute_reply":"2024-01-18T08:53:17.736822Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### Histogram Equalization\nThis method usually increases the global contrast of images. This is done by redistributing pixel intensity.","metadata":{}},{"cell_type":"code","source":"plt.figure(figsize = (18, 4))\n\nplt.subplot(1, 2, 1)\nplt.axis(\"off\")\nplt.title(\"Histogram Equalization\")\n\nimg_he = cv2.equalizeHist(image.numpy())\n\nplt.imshow(img_he, cmap = \"gray\");\n\nplt.subplot(1, 2, 2)\nhist, bins = np.histogram(img_he.flatten(), 256, [0, 256])\ncdf = hist.cumsum()\ncdf_normalized = cdf * float(hist.max()) / cdf.max()\nplt.plot(cdf_normalized, color = 'b')\n\nplt.hist(img_he.flatten(), 256, [0, 256], color = 'r')\nplt.xlim([0, 256])\nplt.legend(('cdf', 'histogram'), loc = 'upper left')\nplt.title(\"Histogram Equalization\")\nplt.show();","metadata":{"execution":{"iopub.status.busy":"2024-01-18T08:53:18.539524Z","iopub.execute_input":"2024-01-18T08:53:18.539917Z","iopub.status.idle":"2024-01-18T08:53:19.348911Z","shell.execute_reply.started":"2024-01-18T08:53:18.539882Z","shell.execute_reply":"2024-01-18T08:53:19.347874Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"A disadvantage of the method is that it is indiscriminate. It may increase the contrast of background noise.","metadata":{}},{"cell_type":"markdown","source":"### Contrast Limited Adaptive Histogram Equalization\nTechnique to improve the contrast of an image. It differs from ordinary histogram equalization in the respect that the adaptive method computes several histograms, each corresponding to a distinct section of the image, and uses them to redistribute the lightness values of the image. Additionally, it prevents over amplification of noise.","metadata":{}},{"cell_type":"code","source":"plt.figure(figsize = (18, 4))\n\nplt.subplot(1, 2, 1)\nplt.axis(\"off\")\nplt.title(\"Contrast Limited Adaptive Histogram Equalization\")\n\nclahe = cv2.createCLAHE(\n    clipLimit = 2., \n    tileGridSize = (10, 10)\n)\n    \nimg_clahe = clahe.apply(image.numpy()) \n\nplt.imshow(img_clahe, cmap = \"gray\");\n\nplt.subplot(1, 2, 2)\nhist, bins = np.histogram(img_clahe.flatten(), 256, [0, 256])\ncdf = hist.cumsum()\ncdf_normalized = cdf * float(hist.max()) / cdf.max()\nplt.plot(cdf_normalized, color = 'b')\n\nplt.hist(img_clahe.flatten(), 256, [0, 256], color = 'r')\nplt.xlim([0, 256])\nplt.legend(('cdf', 'histogram'), loc = 'upper left')\nplt.title(\"Contrast Limited Adaptive Histogram Equalization\")\nplt.show();","metadata":{"execution":{"iopub.status.busy":"2024-01-18T08:53:23.541856Z","iopub.execute_input":"2024-01-18T08:53:23.542283Z","iopub.status.idle":"2024-01-18T08:53:24.513955Z","shell.execute_reply.started":"2024-01-18T08:53:23.542245Z","shell.execute_reply":"2024-01-18T08:53:24.51294Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### Summary","metadata":{}},{"cell_type":"code","source":"plt.figure(figsize = (18, 4))\n\nplt.subplot(1, 3, 1)\nplt.axis(\"off\")\nplt.title(\"Original\")\nplt.imshow(image, cmap = \"gray\");\n\nplt.subplot(1, 3, 2)\nplt.axis(\"off\")\nplt.title(\"Histogram Equalization\")\nplt.imshow(img_he, cmap = \"gray\");\n\nplt.subplot(1, 3, 3)\nplt.axis(\"off\")\nplt.title(\"Contrast Limited Adaptive Histogram Equalization\")\nplt.imshow(img_clahe, cmap = \"gray\");","metadata":{"execution":{"iopub.status.busy":"2024-01-18T08:53:24.697407Z","iopub.execute_input":"2024-01-18T08:53:24.697853Z","iopub.status.idle":"2024-01-18T08:53:25.036319Z","shell.execute_reply.started":"2024-01-18T08:53:24.697805Z","shell.execute_reply":"2024-01-18T08:53:25.034788Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]}]}