{"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":"nvidiaTeslaT4","dataSources":[{"sourceId":6799,"databundleVersionId":4225553,"sourceType":"competition"},{"sourceId":9697599,"sourceType":"datasetVersion","datasetId":5929630}],"dockerImageVersionId":31154,"isInternetEnabled":true,"language":"python","sourceType":"notebook","isGpuEnabled":true}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"!git clone https://github.com/nelson1425/EfficientAD.git","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-11-05T09:06:32.291323Z","iopub.execute_input":"2025-11-05T09:06:32.291498Z","iopub.status.idle":"2025-11-05T09:06:34.74004Z","shell.execute_reply.started":"2025-11-05T09:06:32.291478Z","shell.execute_reply":"2025-11-05T09:06:34.739067Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"!pip install tifffile==2021.7.30 tqdm==4.56.0 scikit-learn==1.2.2","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-11-05T09:06:34.741314Z","iopub.execute_input":"2025-11-05T09:06:34.741595Z","iopub.status.idle":"2025-11-05T09:06:38.191451Z","shell.execute_reply.started":"2025-11-05T09:06:34.741566Z","shell.execute_reply":"2025-11-05T09:06:38.190645Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import os\nimport csv\nimport shutil\nfrom tqdm import tqdm\n\ndef restructure_visa(source_dir: str, target_dir: str, use_symlink: bool = False) -> None:\n    \"\"\"Restructure the VISA dataset into a MVTec-style directory layout.\n\n    Parameters\n    ----------\n    source_dir : str\n        Path to the directory that contains the original VISA dataset\n        (must contain split_csv/1cls.csv).\n    target_dir : str\n        Path where the restructured dataset will be created.\n    use_symlink : bool, optional\n        If True create symbolic links. If False copy the files instead.\n    \"\"\"\n    visa_src = source_dir\n    visa_dst = target_dir\n\n    os.makedirs(visa_dst, exist_ok=True)\n\n    csv_path = \"/kaggle/input/visa-anomaly-detection/split_csv/1cls.csv\"\n    print(\"Using split file:\", csv_path)\n    with open(csv_path, newline=\"\") as file:\n        reader = csv.reader(file)\n        _ = next(reader)  # skip header line\n\n        for _, row in tqdm(enumerate(reader), desc=\"Restructuring\"):\n            class_, split_, label, img_rel_path, mask_rel_path = row\n\n            # File names\n            img_name = os.path.basename(img_rel_path)\n            mask_name = os.path.basename(mask_rel_path) if mask_rel_path else \"\"\n\n            # Map VISA label → folder label\n            label_dir = \"good\" if label == \"normal\" else \"bad\"\n\n            # ---- image ----\n            img_dst_dir = os.path.join(visa_dst, class_, split_, label_dir)\n            os.makedirs(img_dst_dir, exist_ok=True)\n\n            img_src_abs = os.path.join(visa_src, img_rel_path)\n            img_dst_abs = os.path.join(img_dst_dir, img_name)\n\n            _link_or_copy(img_src_abs, img_dst_abs, use_symlink)\n\n            # ---- mask (only for anomalous test samples) ----\n            if not mask_rel_path:\n                continue\n\n            assert split_ == \"test\" and label_dir == \"bad\", (\n                \"Mask present on non-anomalous or non-test sample: \"\n                f\"{class_}/{split_}/{label}\"\n            )\n\n            mask_dst_dir = os.path.join(visa_dst, class_, \"ground_truth\", label_dir)\n            os.makedirs(mask_dst_dir, exist_ok=True)\n\n            mask_src_abs = os.path.join(visa_src, mask_rel_path)\n            mask_dst_abs = os.path.join(mask_dst_dir, mask_name)\n            # Ensure masks end with \"_mask.png\" (MVTec style)\n            if mask_dst_abs.lower().endswith(\".png\"):\n                mask_dst_abs = mask_dst_abs[:-4] + \"_mask.png\"\n\n            _link_or_copy(mask_src_abs, mask_dst_abs, use_symlink)\n\n\ndef _link_or_copy(src: str, dst: str, use_symlink: bool) -> None:\n    \"\"\"Create *dst* pointing to *src* via symlink or copy.\n\n    If *dst* already exists, it is silently overwritten when copying, and left\n    untouched when linking to avoid FileExistsError.\n    \"\"\"\n    if use_symlink:\n        try:\n            os.symlink(src, dst)\n        except FileExistsError:\n            # Keep the existing link to allow re-running the script\n            pass\n    else:\n        # Overwrite if exists\n        shutil.copy2(src, dst)\n\n\n# ======== RUN ON KAGGLE ========\n\nsource_dir = \"/kaggle/input/visa-anomaly-detection\"   # your VisA dataset root\ntarget_dir = \"/kaggle/working/visa_mvtec\"            # where MVTec-style VisA will go\n\nrestructure_visa(source_dir, target_dir, use_symlink=False)\n\nprint(\"Done. Converted VisA is at:\", target_dir)\n","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"!python /kaggle/working/EfficientAD/efficientad.py -a /kaggle/working/visa_mvtec -o /kaggle/working/ --dataset mvtec_ad --subdataset macaroni2 --model_size small --weights /kaggle/working/EfficientAD/models/teacher_small.pth --imagenet_train_path /kaggle/input/imagenet-object-localization-challenge/ILSVRC/Data/CLS-LOC/train\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-11-04T16:28:46.466494Z","iopub.execute_input":"2025-11-04T16:28:46.466874Z","execution_failed":"2025-11-04T16:34:40.529Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"!rm -rf /kaggle/working/visa_mvtec\n!rm -rf /kaggle/working/EfficientAD","metadata":{"trusted":true},"outputs":[],"execution_count":null}]}