{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"name":"python","version":"3.12.12","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"},"kaggle":{"accelerator":"gpu","dataSources":[{"sourceType":"competition","sourceId":24800,"datasetId":1042002,"databundleVersionId":1831594}],"dockerImageVersionId":31260,"isInternetEnabled":true,"language":"python","sourceType":"notebook","isGpuEnabled":true}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"# This Python 3 environment comes with many helpful analytics libraries installed\n# It is defined by the kaggle/python Docker image: https://github.com/kaggle/docker-python\n# For example, here's several helpful packages to load\n\nimport numpy as np # linear algebra\nimport pandas as pd # data processing, CSV file I/O (e.g. pd.read_csv)\n\n# Input data files are available in the read-only \"../input/\" directory\n# For example, running this (by clicking run or pressing Shift+Enter) will list all files under the input directory\n\nimport os\nfor dirname, _, filenames in os.walk('/kaggle/input'):\n    for filename in filenames:\n        print(os.path.join(dirname, filename))\n\n# You can write up to 20GB to the current directory (/kaggle/working/) that gets preserved as output when you create a version using \"Save & Run All\" \n# You can also write temporary files to /kaggle/temp/, but they won't be saved outside of the current session","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true,"execution":{"iopub.status.busy":"2026-02-18T18:04:31.259947Z","iopub.execute_input":"2026-02-18T18:04:31.260279Z","iopub.status.idle":"2026-02-18T18:04:51.03367Z","shell.execute_reply.started":"2026-02-18T18:04:31.260247Z","shell.execute_reply":"2026-02-18T18:04:51.03257Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"!pip install -qU python-gdcm pydicom pylibjpeg pylibjpeg-libjpeg\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-02-18T18:04:51.035548Z","iopub.execute_input":"2026-02-18T18:04:51.035938Z","iopub.status.idle":"2026-02-18T18:04:57.553793Z","shell.execute_reply.started":"2026-02-18T18:04:51.035913Z","shell.execute_reply":"2026-02-18T18:04:57.553108Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import os\nimport cv2\nimport pydicom\nimport numpy as np\nfrom tqdm.auto import tqdm\nfrom joblib import Parallel, delayed\nfrom pydicom.pixel_data_handlers.util import apply_voi_lut\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-02-18T18:04:57.555027Z","iopub.execute_input":"2026-02-18T18:04:57.555288Z","iopub.status.idle":"2026-02-18T18:04:58.772318Z","shell.execute_reply.started":"2026-02-18T18:04:57.555262Z","shell.execute_reply":"2026-02-18T18:04:58.771788Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"INPUT_DIR = \"../input/vinbigdata-chest-xray-abnormalities-detection/train\"\nOUTPUT_DIR = \"/kaggle/working/train_png\"\nSIZE = 512   # Best size for ML balance\n\nos.makedirs(OUTPUT_DIR, exist_ok=True)\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-02-18T18:04:58.773124Z","iopub.execute_input":"2026-02-18T18:04:58.773344Z","iopub.status.idle":"2026-02-18T18:04:58.777127Z","shell.execute_reply.started":"2026-02-18T18:04:58.773322Z","shell.execute_reply":"2026-02-18T18:04:58.776523Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"def process_dicom(file_name):\n    try:\n        path = os.path.join(INPUT_DIR, file_name)\n        dicom = pydicom.dcmread(path)\n\n        # Apply medical contrast LUT\n        image = apply_voi_lut(dicom.pixel_array, dicom)\n\n        # Fix inverted grayscale (important for X-rays)\n        if dicom.PhotometricInterpretation == \"MONOCHROME1\":\n            image = np.amax(image) - image\n\n        # Normalize safely\n        image = image - np.min(image)\n        max_val = np.max(image)\n        if max_val != 0:\n            image = image / max_val\n\n        image = (image * 255).astype(np.uint8)\n\n        # Resize for ML\n        image = cv2.resize(image, (SIZE, SIZE))\n\n        # Save as PNG\n        out_path = os.path.join(OUTPUT_DIR, file_name.replace(\".dicom\", \".png\"))\n        cv2.imwrite(out_path, image)\n\n    except Exception:\n        pass","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-02-18T18:04:58.778194Z","iopub.execute_input":"2026-02-18T18:04:58.77838Z","iopub.status.idle":"2026-02-18T18:04:58.790609Z","shell.execute_reply.started":"2026-02-18T18:04:58.77836Z","shell.execute_reply":"2026-02-18T18:04:58.789868Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"files = [f for f in os.listdir(INPUT_DIR) if f.endswith(\".dicom\")]\n\nParallel(n_jobs=4)(\n    delayed(process_dicom)(f) for f in tqdm(files)\n)\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-02-18T18:04:58.791547Z","iopub.execute_input":"2026-02-18T18:04:58.791914Z","iopub.status.idle":"2026-02-18T18:57:36.959414Z","shell.execute_reply.started":"2026-02-18T18:04:58.791882Z","shell.execute_reply":"2026-02-18T18:57:36.958523Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"print(\"Total images:\", len(os.listdir(OUTPUT_DIR)))\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-02-18T18:57:36.961438Z","iopub.execute_input":"2026-02-18T18:57:36.961708Z","iopub.status.idle":"2026-02-18T18:57:36.987289Z","shell.execute_reply.started":"2026-02-18T18:57:36.961664Z","shell.execute_reply":"2026-02-18T18:57:36.986749Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"!tar -zcf vinbigdata_png_512.tar.gz -C /kaggle/working/train_png .\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-02-18T18:57:36.988063Z","iopub.execute_input":"2026-02-18T18:57:36.98827Z","iopub.status.idle":"2026-02-18T18:58:58.782844Z","shell.execute_reply.started":"2026-02-18T18:57:36.988251Z","shell.execute_reply":"2026-02-18T18:58:58.781878Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"","metadata":{}},{"cell_type":"code","source":"import pandas as pd\n\ncsv_path = \"/kaggle/input/vinbigdata-chest-xray-abnormalities-detection/train.csv\"\ndf = pd.read_csv(csv_path)\n\nprint(\"Total annotation rows:\", len(df))\ndf.head()\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-02-19T05:42:35.932796Z","iopub.execute_input":"2026-02-19T05:42:35.933507Z","iopub.status.idle":"2026-02-19T05:42:37.9667Z","shell.execute_reply.started":"2026-02-19T05:42:35.933479Z","shell.execute_reply":"2026-02-19T05:42:37.966102Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import os\nimport pandas as pd\n\n# ---- PATHS ----\nCSV_PATH = \"/kaggle/input/vinbigdata-chest-xray-abnormalities-detection/train.csv\"\nIMG_SIZE = 512\nLABEL_DIR = \"/kaggle/working/labels\"\n\nos.makedirs(LABEL_DIR, exist_ok=True)\n\n# ---- LOAD CSV ----\ndf = pd.read_csv(CSV_PATH)\nprint(\"Annotations loaded:\", len(df))\n\n# ---- CREATE YOLO LABEL FILES ----\ncount = 0\n\nfor image_id, group in df.groupby(\"image_id\"):\n    \n    label_path = os.path.join(LABEL_DIR, image_id + \".txt\")\n    \n    with open(label_path, \"w\") as f:\n        for _, row in group.iterrows():\n            \n            # skip no finding\n            if row.class_name == \"No finding\":\n                continue\n            \n            # skip rows without boxes\n            if pd.isna(row.x_min):\n                continue\n            \n            x1, y1, x2, y2 = row.x_min, row.y_min, row.x_max, row.y_max\n            \n            # convert to YOLO format\n            x_center = ((x1 + x2) / 2) / IMG_SIZE\n            y_center = ((y1 + y2) / 2) / IMG_SIZE\n            width = (x2 - x1) / IMG_SIZE\n            height = (y2 - y1) / IMG_SIZE\n            \n            f.write(f\"{int(row.class_id)} {x_center} {y_center} {width} {height}\\n\")\n    \n    count += 1\n\nprint(\"Label files created:\", count)\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-02-19T05:44:38.855486Z","iopub.execute_input":"2026-02-19T05:44:38.855809Z","iopub.status.idle":"2026-02-19T05:44:45.97341Z","shell.execute_reply.started":"2026-02-19T05:44:38.855785Z","shell.execute_reply":"2026-02-19T05:44:45.972576Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"print(\"Total label files:\", len(os.listdir(LABEL_DIR)))\nprint(\"Example label file:\")\nprint(os.listdir(LABEL_DIR)[:5])\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-02-19T05:46:54.617995Z","iopub.execute_input":"2026-02-19T05:46:54.618394Z","iopub.status.idle":"2026-02-19T05:46:54.642738Z","shell.execute_reply.started":"2026-02-19T05:46:54.618365Z","shell.execute_reply":"2026-02-19T05:46:54.64207Z"}},"outputs":[],"execution_count":null}]}