{"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"},"kaggle":{"accelerator":"none","dataSources":[{"sourceType":"competition","sourceId":39272,"databundleVersionId":4629629,"isSourceIdPinned":false}],"isInternetEnabled":true,"language":"python","sourceType":"notebook","isGpuEnabled":false}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"!pip install pylibjpeg pylibjpeg-libjpeg -q","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import os\nimport numpy as np\nimport pydicom\nfrom pydicom.pixel_data_handlers.util import apply_voi_lut\nfrom PIL import Image\nfrom pathlib import Path\nfrom tqdm import tqdm\n\n# ─── CONFIG ───────────────────────────────────────────────────────────────────\nINPUT_DIR  = Path(\"/kaggle/input/competitions/rsna-breast-cancer-detection/train_images\")\nOUTPUT_DIR = Path(\"/kaggle/working/train_images_png\")\nTARGET_SIZE = 768\nP_LOW, P_HIGH = 1, 99\n# ──────────────────────────────────────────────────────────────────────────────\n\ndef dicom_to_array(dcm_path):\n    dcm = pydicom.dcmread(dcm_path)\n    img = apply_voi_lut(dcm.pixel_array, dcm)\n    if dcm.PhotometricInterpretation == \"MONOCHROME1\":\n        img = img.max() - img\n    img = img.astype(np.float32)\n    lo, hi = np.percentile(img, [P_LOW, P_HIGH])\n    img = np.clip(img, lo, hi)\n    if hi > lo:\n        img = (img - lo) / (hi - lo)\n    else:\n        img = np.zeros_like(img)\n    return img\n\ndef letterbox(img, size=TARGET_SIZE):\n    h, w = img.shape\n    scale = size / max(h, w)\n    new_h, new_w = int(round(h * scale)), int(round(w * scale))\n    pil_img = Image.fromarray((img * 255).astype(np.uint8))\n    pil_img = pil_img.resize((new_w, new_h), Image.LANCZOS)\n    resized = np.array(pil_img, dtype=np.float32) / 255.0\n    canvas  = np.zeros((size, size), dtype=np.float32)\n    pad_top  = (size - new_h) // 2\n    pad_left = (size - new_w) // 2\n    canvas[pad_top:pad_top+new_h, pad_left:pad_left+new_w] = resized\n    return canvas\n\ndef process_dicom(dcm_path, out_path):\n    img = dicom_to_array(dcm_path)\n    img = letterbox(img, TARGET_SIZE)\n    img_uint8 = (img * 255).astype(np.uint8)\n    out_path.parent.mkdir(parents=True, exist_ok=True)\n    Image.fromarray(img_uint8).convert(\"L\").save(out_path, format=\"PNG\")\n\ndef process_dataset(start=0, end=None):\n    all_files = sorted(INPUT_DIR.rglob(\"*.dcm\"))\n    files = all_files[start:end]\n    print(f\"Processing files {start} to {end or len(all_files)} ({len(files)} total)\")\n\n    for dcm_path in tqdm(files, desc=\"Converting\"):\n        rel = dcm_path.relative_to(INPUT_DIR)\n        out = (OUTPUT_DIR / rel).with_suffix(\".png\")\n        if out.exists():           # skip already converted\n            continue\n        try:\n            process_dicom(dcm_path, out)\n        except Exception as e:\n            print(f\"\\n[ERROR] {dcm_path.name}: {e}\")\n\n    print(f\"\\nDone!\")","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"process_dataset(start=45000)              # Session 6 (till the end)          # Session 6 (till the end)","metadata":{"trusted":true},"outputs":[],"execution_count":null}]}