{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"name":"python","version":"3.11.13","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":31192,"isInternetEnabled":true,"language":"python","sourceType":"notebook","isGpuEnabled":false}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"import os\nimport pydicom\nimport cv2\nimport numpy as np\nfrom tqdm import tqdm\nfrom PIL import Image\nimport concurrent.futures\n\n# Cấu hình\nINPUT_DIR = \"/kaggle/input/vinbigdata-chest-xray-abnormalities-detection/test\"\nOUTPUT_DIR = \"/kaggle/working/test_png_384\"\nIMG_SIZE = 384\n\nos.makedirs(OUTPUT_DIR, exist_ok=True)\n\ndef convert_one_image(filename):\n    if not filename.endswith('.dicom'): return\n    \n    file_path = os.path.join(INPUT_DIR, filename)\n    save_path = os.path.join(OUTPUT_DIR, filename.replace('.dicom', '.png'))\n    \n    # Nếu file đã tồn tại thì bỏ qua (resume)\n    if os.path.exists(save_path): return\n\n    try:\n        # Đọc DICOM\n        dicom = pydicom.dcmread(file_path)\n        pixel_array = dicom.pixel_array\n        \n        # Photometric Interpretation handling (quan trọng cho X-Ray)\n        if dicom.PhotometricInterpretation == \"MONOCHROME1\":\n            pixel_array = np.max(pixel_array) - pixel_array\n            \n        # Normalize về 0-255\n        pixel_array = pixel_array.astype(np.float32)\n        pixel_array = (pixel_array - pixel_array.min()) / (pixel_array.max() - pixel_array.min()) * 255.0\n        pixel_array = pixel_array.astype(np.uint8)\n        \n        # Resize\n        img = cv2.resize(pixel_array, (IMG_SIZE, IMG_SIZE))\n        \n        # Save PNG\n        cv2.imwrite(save_path, img)\n    except Exception as e:\n        print(f\"Error converting {filename}: {e}\")\n\n# Chạy đa luồng (Kaggle CPU có 4 cores)\nfiles = os.listdir(INPUT_DIR)\nwith concurrent.futures.ThreadPoolExecutor(max_workers=4) as executor:\n    list(tqdm(executor.map(convert_one_image, files), total=len(files)))","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true,"execution":{"iopub.status.busy":"2026-02-02T01:51:21.460853Z","iopub.execute_input":"2026-02-02T01:51:21.46106Z"}},"outputs":[],"execution_count":null}]}