{"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":"<center><h1> SIIM-FISABIO-RSNA COVID-19 Detection </h1></center><br>","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19"}},{"cell_type":"markdown","source":"# What is .DCM format\n\nThe DCM file extension is used for DICOM which stands for Digital Imaging and Communications in Medicine. This is the common file format used to store medical imaging data when a patient undergoes a CT, MRI, PET, UltraSound, and many other types of medical scans\n\n📌<b>DICOM : Digital Imaging and Communication in Medicine</b><br>\n\n<b>About DICOM</b><br>\n\nDICOM® — Digital Imaging and Communications in Medicine — is the international standard for medical images and related information. It defines the formats for medical images that can be exchanged with the data and quality necessary for clinical use.\n\nDICOM® is implemented in almost every radiology, cardiology imaging, and radiotherapy device (X-ray, CT, MRI, ultrasound, etc.), and increasingly in devices in other medical domains such as ophthalmology and dentistry. With hundreds of thousands of medical imaging devices in use, DICOM® is one of the most widely deployed healthcare messaging Standards in the world. There are literally billions of DICOM® images currently in use for clinical care.\n\nSince its first publication in 1993, DICOM® has revolutionized the practice of radiology, allowing the replacement of X-ray film with a fully digital workflow. Much as the Internet has become the platform for new consumer information applications, DICOM® has enabled advanced medical imaging applications that have “changed the face of clinical medicine”. From the emergency department, to cardiac stress testing, to breast cancer detection, DICOM® is the standard that makes medical imaging work — for doctors and for patients.\n\nDICOM® is recognized by the International Organization for Standardization as the ISO 12052 standard.\n\n<b>Data format</b><br>\n\n<img src='https://formats.kaitai.io/dicom/dicom.svg'><br>\nDICOM groups information into data sets. For example, a file of a chest x-ray image may contain the patient ID within the file, so that the image can never be separated from this information by mistake. This is similar to the way that image formats such as JPEG can also have embedded tags to identify and otherwise describe the image.\n\nA DICOM data object consists of a number of attributes, including items such as name, ID, etc., and also one special attribute containing the image pixel data (i.e. logically, the main object has no \"header\" as such, being merely a list of attributes, including the pixel data). A single DICOM object can have only one attribute containing pixel data. For many modalities, this corresponds to a single image. However, the attribute may contain multiple \"frames\", allowing storage of cine loops or other multi-frame data. Another example is NM data, where an NM image, by definition, is a multi-dimensional multi-frame image. In these cases, three- or four-dimensional data can be encapsulated in a single DICOM object. Pixel data can be compressed using a variety of standards, including JPEG, lossless JPEG, JPEG 2000, and run-length encoding (RLE). LZW (zip) compression can be used for the whole data set (not just the pixel data), but this has rarely been implemented.\n\nDICOM uses three different data element encoding schemes. With explicit value representation (VR) data elements, for VRs that are not OB, OW, OF, SQ, UT, or UN[clarification needed], the format for each data element is: GROUP (2 bytes) ELEMENT (2 bytes) VR (2 bytes) LengthInByte (2 bytes) Data (variable length). For the other explicit data elements or implicit data elements, see section 7.1 of Part 5 of the DICOM Standard.\n\nThe same basic format is used for all applications, including network and file usage, but when written to a file, usually a true \"header\" (containing copies of a few key attributes and details of the application that wrote it) is added.\n\nDICOM official homepage link : https://www.dicomstandard.org/<br>\nDICOM wiki link : https://en.wikipedia.org/wiki/DICOM","metadata":{}},{"cell_type":"markdown","source":"# Pydicom\n\nPydicom is a pure Python package for working with DICOM files such as medical images, reports, and radiotherapy objects. Pydicom makes it easy to read these complex files into natural pythonic structures for easy manipulation. Modified datasets can be written again to DICOM format files.\n\nPydicom Github link : https://github.com/pydicom<br>\nPydicom blog link : https://pydicom.github.io/pydicom/stable/#\n","metadata":{}},{"cell_type":"markdown","source":"### Libraries","metadata":{}},{"cell_type":"code","source":"import os\nimport cv2\nimport warnings\nfrom glob import glob\nimport pandas as pd\nimport numpy as np\nimport matplotlib as mpl\nimport matplotlib.pyplot as plt\nimport pydicom\nfrom pydicom.pixel_data_handlers.util import apply_voi_lut\n\nwarnings.filterwarnings('ignore')","metadata":{"execution":{"iopub.status.busy":"2021-05-20T13:55:27.285375Z","iopub.execute_input":"2021-05-20T13:55:27.285785Z","iopub.status.idle":"2021-05-20T13:55:27.290897Z","shell.execute_reply.started":"2021-05-20T13:55:27.285747Z","shell.execute_reply":"2021-05-20T13:55:27.290170Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Convert a DICOM Dataset to Image\n\n<b>Progress</b><br>\n<img src='https://t1.daumcdn.net/cfile/tistory/9979A1365EF2EFBA21'><br>\n\n\n### Read a DICOM Dataset\n\nreference url : https://pydicom.github.io/pydicom/stable/auto_examples/input_output/plot_read_dicom.html#sphx-glr-auto-examples-input-output-plot-read-dicom-py","metadata":{}},{"cell_type":"code","source":"dataset_dir = '../input/siim-covid19-detection'\n\ndicom_paths = glob(f'{dataset_dir}/train/*/*/*.dcm')\nfor path in dicom_paths[:5]:\n    print(path)","metadata":{"execution":{"iopub.status.busy":"2021-05-20T13:55:27.350065Z","iopub.execute_input":"2021-05-20T13:55:27.350610Z","iopub.status.idle":"2021-05-20T13:55:32.943573Z","shell.execute_reply.started":"2021-05-20T13:55:27.350561Z","shell.execute_reply":"2021-05-20T13:55:32.942507Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### Print a DICOM Dataset\n\nreference url : https://github.com/pydicom/pydicom/issues/319","metadata":{}},{"cell_type":"code","source":"def dicom_dataset_to_dict(dicom_header):\n    dicom_dict = {}\n    repr(dicom_header)\n    for dicom_value in dicom_header.values():\n        if dicom_value.tag == (0x7fe0, 0x0010):\n            # discard pixel data\n            continue\n        if type(dicom_value.value) == pydicom.dataset.Dataset:\n            dicom_dict[dicom_value.name] = dicom_dataset_to_dict(dicom_value.value)\n        else:\n            v = _convert_value(dicom_value.value)\n            dicom_dict[dicom_value.name] = v\n    \n    for d in dicom_dict:\n        print('{} : {}'.format(d, dicom_dict[d]))\n\n\ndef _sanitise_unicode(s):\n    return s.replace(u\"\\u0000\", \"\").strip()\n\n\ndef _convert_value(v):\n    t = type(v)\n    if t in (list, int, float):\n        cv = v\n    elif t == str:\n        cv = _sanitise_unicode(v)\n    elif t == bytes:\n        s = v.decode('ascii', 'replace')\n        cv = _sanitise_unicode(s)\n    elif t == pydicom.valuerep.DSfloat:\n        cv = float(v)\n    elif t == pydicom.valuerep.IS:\n        cv = int(v)\n    else:\n        cv = repr(v)\n    return cv","metadata":{"execution":{"iopub.status.busy":"2021-05-20T13:55:32.945488Z","iopub.execute_input":"2021-05-20T13:55:32.945958Z","iopub.status.idle":"2021-05-20T13:55:32.957009Z","shell.execute_reply.started":"2021-05-20T13:55:32.945910Z","shell.execute_reply":"2021-05-20T13:55:32.955914Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"ds = pydicom.dcmread(dicom_paths[0])\ndicom_dataset_to_dict(ds)","metadata":{"execution":{"iopub.status.busy":"2021-05-20T13:55:32.958572Z","iopub.execute_input":"2021-05-20T13:55:32.959010Z","iopub.status.idle":"2021-05-20T13:55:32.996477Z","shell.execute_reply.started":"2021-05-20T13:55:32.958967Z","shell.execute_reply":"2021-05-20T13:55:32.995513Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### Simple Method of looking at the Images","metadata":{}},{"cell_type":"code","source":"fig, ax = plt.subplots(1, 3, figsize=(18,6))\n\nds0 = pydicom.dcmread(dicom_paths[0]).pixel_array\nds1 = pydicom.dcmread(dicom_paths[1]).pixel_array\nds2 = pydicom.dcmread(dicom_paths[2]).pixel_array\n\nax[0].imshow(ds0)\nax[1].imshow(ds1, cmap=plt.cm.bone)\nax[2].imshow(ds2, cmap='gray')\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2021-05-20T13:55:32.998362Z","iopub.execute_input":"2021-05-20T13:55:32.998679Z","iopub.status.idle":"2021-05-20T13:55:36.250920Z","shell.execute_reply.started":"2021-05-20T13:55:32.998648Z","shell.execute_reply":"2021-05-20T13:55:36.249849Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### Hounsfiled Unit (HU) ###\n\n📌<b>About Hounsfiled Unit</b><br>\n    \nThe Hounsfield unit (HU) scale is a linear transformation of the original linear attenuation coefficient measurement into one in which the radiodensity of distilled water at standard pressure and temperature (STP) is defined as zero Hounsfield units (HU), while the radiodensity of air at STP is defined as −1000 HU. In a voxel with average linear attenuation coefficient {\\displaystyle \\mu }\\mu , the corresponding HU value is therefore given by:\n\n<img src='https://wikimedia.org/api/rest_v1/media/math/render/svg/ecfb5f44205930f7a33a9c240f41eb94051f3f01'/><br>\n\nThus, a change of one Hounsfield unit (HU) represents a change of 0.1% of the attenuation coefficient of water since the attenuation coefficient of air is nearly zero.\nIt is the definition for CT scanners that are calibrated with reference to water.\n<br>\n    \n<b> Values for Different body tissues and material</b><br>\n\n<img src = 'https://t1.daumcdn.net/cfile/tistory/99A51D3E5EF2F3B226'/><br>\nHU applies to medical-grade dual-energy CT scans but not to cone beam computed tomography (CBCT) scans.\nValues reported here are approximations. Different dynamics are reported from one study to another.\nExact HU dynamics can vary from one CT acquisition to another due to CT acquisition and reconstruction parameters (kV, filters, reconstruction algorithms, etc.). The use of contrast agents modifies HU as well in some body parts (mainly blood).\n\nHU Table url : https://en.wikipedia.org/wiki/Hounsfield_scale","metadata":{}},{"cell_type":"markdown","source":"### apply_voi_lut ###\n\nreference url : https://www.kaggle.com/tanlikesmath/siim-covid-19-detection-a-simple-eda","metadata":{}},{"cell_type":"code","source":"def dicom2array(path, voi_lut=True, fix_monochrome=True):\n    dicom = pydicom.read_file(path)\n    # VOI LUT (if available by DICOM device) is used to\n    # transform raw DICOM data to \"human-friendly\" view\n    if voi_lut:\n        data = apply_voi_lut(dicom.pixel_array, dicom)\n    else:\n        data = dicom.pixel_array\n    # depending on this value, X-ray may look inverted - fix that:\n    if fix_monochrome and dicom.PhotometricInterpretation == \"MONOCHROME1\":\n        data = np.amax(data) - data\n    data = data - np.min(data)\n    data = data / np.max(data)\n    data = (data * 255).astype(np.uint8)\n    return data\n        \n    \ndef plot_img(img, size=(7, 7), is_rgb=True, title=\"\", cmap='gray'):\n    plt.figure(figsize=size)\n    plt.imshow(img, cmap=cmap)\n    plt.suptitle(title)\n    plt.show()\n\n\ndef plot_imgs(imgs, cols=4, size=7, is_rgb=True, title=\"\", cmap='gray', img_size=(500,500)):\n    rows = len(imgs)//cols + 1\n    fig = plt.figure(figsize=(cols*size, rows*size))\n    for i, img in enumerate(imgs):\n        if img_size is not None:\n            img = cv2.resize(img, img_size)\n        fig.add_subplot(rows, cols, i+1)\n        plt.imshow(img, cmap=plt.cm.bone)\n    plt.suptitle(title)\n    plt.show()","metadata":{"execution":{"iopub.status.busy":"2021-05-20T13:55:36.252462Z","iopub.execute_input":"2021-05-20T13:55:36.252773Z","iopub.status.idle":"2021-05-20T13:55:36.263535Z","shell.execute_reply.started":"2021-05-20T13:55:36.252744Z","shell.execute_reply":"2021-05-20T13:55:36.262831Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"fig, ax = plt.subplots(1, 2, figsize=(18, 6))\n\nds0 = pydicom.dcmread(dicom_paths[0]).pixel_array\nds1 = dicom2array(dicom_paths[0])\n\nax[0].imshow(ds0, cmap=plt.cm.bone)\nax[0].set_title('DICOM -> Array')\nax[1].imshow(ds1, cmap=plt.cm.bone)\nax[1].set_title('apply_voi_lut( )')\n\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2021-05-20T13:55:36.264399Z","iopub.execute_input":"2021-05-20T13:55:36.264672Z","iopub.status.idle":"2021-05-20T13:55:38.040673Z","shell.execute_reply.started":"2021-05-20T13:55:36.264645Z","shell.execute_reply":"2021-05-20T13:55:38.039620Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"imgs = [dicom2array(path) for path in dicom_paths[:16]]\nplot_imgs(imgs)","metadata":{"execution":{"iopub.status.busy":"2021-05-20T13:55:38.042129Z","iopub.execute_input":"2021-05-20T13:55:38.042700Z","iopub.status.idle":"2021-05-20T13:55:42.733803Z","shell.execute_reply.started":"2021-05-20T13:55:38.042656Z","shell.execute_reply":"2021-05-20T13:55:42.733011Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"#### Thanks for reading my work","metadata":{}}]}