{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"name":"python","version":"3.11.11","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"},"kaggle":{"accelerator":"gpu","dataSources":[{"sourceId":30201,"databundleVersionId":2750748,"sourceType":"competition"},{"sourceId":11977273,"sourceType":"datasetVersion","datasetId":7510849},{"sourceId":11987188,"sourceType":"datasetVersion","datasetId":7510607}],"dockerImageVersionId":31041,"isInternetEnabled":false,"language":"python","sourceType":"notebook","isGpuEnabled":true}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"!pip install --no-index --find-links /kaggle/input/cellpose-whl --no-deps cellpose fastremap fill_voids roifile","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true,"execution":{"iopub.status.busy":"2025-05-28T02:11:47.37466Z","iopub.execute_input":"2025-05-28T02:11:47.374976Z","iopub.status.idle":"2025-05-28T02:11:48.787326Z","shell.execute_reply.started":"2025-05-28T02:11:47.374948Z","shell.execute_reply":"2025-05-28T02:11:48.786564Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"from cellpose import models, io\nimport numpy as np\nimport pandas as pd\nfrom pathlib import Path\nimport cv2\n\nmodel = models.CellposeModel(gpu=True, pretrained_model='/kaggle/input/my-cellpose-models/best_model_0.3044677972793579.pth')","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-05-27T15:33:47.621742Z","iopub.execute_input":"2025-05-27T15:33:47.6225Z","iopub.status.idle":"2025-05-27T15:34:25.178487Z","shell.execute_reply.started":"2025-05-27T15:33:47.622467Z","shell.execute_reply":"2025-05-27T15:34:25.177941Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"def rle_encode(img):\n    '''\n    img: numpy array, 1 - foreground, 0 - background\n    Returns run length as string\n    '''\n    pixels = img.flatten()\n    pixels = np.concatenate([[0], pixels, [0]])\n    runs = np.where(pixels[1:] != pixels[:-1])[0] + 1\n    runs[1::2] -= runs[::2]\n    return ' '.join(str(x) for x in runs)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-05-27T15:34:43.69306Z","iopub.execute_input":"2025-05-27T15:34:43.693881Z","iopub.status.idle":"2025-05-27T15:34:43.698391Z","shell.execute_reply.started":"2025-05-27T15:34:43.693854Z","shell.execute_reply":"2025-05-27T15:34:43.697687Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"test_dir = Path('/kaggle/input/sartorius-cell-instance-segmentation/test')\ntest_files = sorted([f for f in test_dir.iterdir() if f.suffix == '.png']) # 假設圖片是.png格式\n\nsubmission_data = []\n\n\nfor img_path in test_files:\n    img_id = img_path.stem\n    img = io.imread(img_path)\n\n    masks = model.eval(img, tile_overlap=0.5)[0]\n\n    if masks.ndim == 2:\n        num_instances = masks.max()\n        for i in range(1, num_instances + 1):\n            mask_instance = (masks == i).astype(np.uint8)\n            rle = rle_encode(mask_instance)\n            submission_data.append({'id': img_id, 'predicted': rle})\n    else:\n        print(f\"Warning: Unexpected masks dimension for {img_id}. Skipping.\")\n\n\nsubmission_df = pd.DataFrame(submission_data)\n\n\nall_test_ids = [f.stem for f in test_files]\nmissing_ids = set(all_test_ids) - set(submission_df['id'].unique())\nfor img_id in missing_ids:\n    submission_df = pd.concat([submission_df, pd.DataFrame([{'id': img_id, 'predicted': ''}])], ignore_index=True)\n\nsubmission_df = submission_df.sort_values(by='id').reset_index(drop=True)\n\nsubmission_df.to_csv('submission.csv', index=False)\n\nprint(\"Submission file 'submission.csv' created successfully!\")","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-05-27T15:34:45.977669Z","iopub.execute_input":"2025-05-27T15:34:45.977973Z","iopub.status.idle":"2025-05-27T15:36:38.23225Z","shell.execute_reply.started":"2025-05-27T15:34:45.977943Z","shell.execute_reply":"2025-05-27T15:36:38.2315Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# ✅ 終端輸出資訊\nprint(submission_df.head())\nprint(\"欄位名稱:\", submission_df.columns)\nprint(\"是否有重複 id:\", submission_df['id'].duplicated().any())\nprint(\"是否有 null:\", submission_df.isnull().sum())\nprint(\"是否有空字串以外的空值:\", (submission_df['predicted'].astype(str).str.strip() == '').sum())\nprint(\"id 總數:\", submission_df['id'].nunique(), \"submission 行數:\", len(submission_df))\nprint(\"predicted 欄型別:\", submission_df['predicted'].apply(type).value_counts())\nprint(\"✅ Submission file 'submission.csv' created successfully!\")","metadata":{"trusted":true},"outputs":[],"execution_count":null}]}