{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"name":"python","version":"3.10.12","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"},"kaggle":{"accelerator":"none","dataSources":[{"sourceId":91249,"databundleVersionId":11294684,"sourceType":"competition"}],"dockerImageVersionId":30918,"isInternetEnabled":true,"language":"python","sourceType":"notebook","isGpuEnabled":false}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"markdown","source":"# BYU Locating Flagellar Motors\n\nThis is individual code preparing dataset.\n\nCitation:\n\n1. **[Parse Data](https://www.kaggle.com/code/andrewjdarley/parse-data)**: Extracting and preparing 2D slices containing motors to make a YOLO dataset\n2. **[Visualize Data](https://www.kaggle.com/code/andrewjdarley/visualize-data)**: Exploratory data analysis and visualization of annotated motor locations\n\nNext I will test:\n\n3. **[Train YOLO](https://www.kaggle.com/code/andrewjdarley/train-yolo)**: Fine tuning an YOLOv8 object detection model on the prepared dataset\n4. **[Submission Notebook](https://www.kaggle.com/code/andrewjdarley/submission-notebook)**: Running inference and generating submission files\n","metadata":{}},{"cell_type":"code","source":"import os\nimport numpy as np\nimport pandas as pd\nfrom PIL import Image\nimport shutil\nimport time\nimport yaml\nfrom pathlib import Path\nfrom tqdm.notebook import tqdm  # Use tqdm.notebook for Jupyter/Kaggle environments\nimport glob\n\nimport matplotlib.pyplot as plt\nimport matplotlib.patches as patches\nimport math\n\n# Set random seed for reproducibility\nnp.random.seed(42)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-05-11T09:51:33.210166Z","iopub.execute_input":"2025-05-11T09:51:33.210643Z","iopub.status.idle":"2025-05-11T09:51:33.818203Z","shell.execute_reply.started":"2025-05-11T09:51:33.210600Z","shell.execute_reply":"2025-05-11T09:51:33.817164Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Define Kaggle paths\ndata_path = \"/kaggle/input/byu-locating-bacterial-flagellar-motors-2025/\"\ntrain_dir = os.path.join(data_path, \"train\")\n\n# Define YOLO dataset structure\nyolo_dataset_dir = \"/kaggle/working/yolo_dataset\"\nyolo_images_train = os.path.join(yolo_dataset_dir, \"images\", \"train\")\nyolo_images_val = os.path.join(yolo_dataset_dir, \"images\", \"val\")\nyolo_labels_train = os.path.join(yolo_dataset_dir, \"labels\", \"train\")\nyolo_labels_val = os.path.join(yolo_dataset_dir, \"labels\", \"val\")\n\n# Create directories\nfor dir_path in [yolo_images_train, yolo_images_val, yolo_labels_train, yolo_labels_val]:\n    os.makedirs(dir_path, exist_ok=True)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-05-11T09:51:36.414177Z","iopub.execute_input":"2025-05-11T09:51:36.414672Z","iopub.status.idle":"2025-05-11T09:51:36.420813Z","shell.execute_reply.started":"2025-05-11T09:51:36.414641Z","shell.execute_reply":"2025-05-11T09:51:36.419812Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"# check submission style","metadata":{}},{"cell_type":"code","source":"# check submission style\nsubmission_path = data_path+'sample_submission.csv'\nsubmission_df = pd.read_csv(submission_path)\nsubmission_df","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-05-11T09:51:39.304628Z","iopub.execute_input":"2025-05-11T09:51:39.304963Z","iopub.status.idle":"2025-05-11T09:51:39.343313Z","shell.execute_reply.started":"2025-05-11T09:51:39.304937Z","shell.execute_reply":"2025-05-11T09:51:39.342271Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"# check train labels","metadata":{}},{"cell_type":"code","source":"# check submission style\ntrain_labels_path = data_path+'train_labels.csv'\ntrain_labels = pd.read_csv(train_labels_path)\ntrain_labels.head(10)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-05-11T09:51:40.547741Z","iopub.execute_input":"2025-05-11T09:51:40.548044Z","iopub.status.idle":"2025-05-11T09:51:40.571053Z","shell.execute_reply.started":"2025-05-11T09:51:40.548020Z","shell.execute_reply":"2025-05-11T09:51:40.569942Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"# look at tomo_003acc data","metadata":{}},{"cell_type":"code","source":"def show_train_image(image_subdir,start_idx=0):\n    image_pattern = '*.jpg'\n    # グリッドの列数 (1行に何枚の画像を表示するか)\n    # 必要に応じて調整してください\n    cols = 5\n    \n    # 表示する画像の最大数 (多すぎると表示に時間がかかる場合やメモリを消費する場合があるため)\n    # None にすると見つかった画像を全て表示\n    max_images_to_display = 25\n    \n    # --- 処理 ---\n    # 画像ファイルのパスリストを取得\n    search_path = f\"{train_dir}/{image_subdir}/{image_pattern}\"\n    image_paths = glob.glob(search_path)\n    image_paths = sorted(image_paths)\n\n    print(f\"{len(image_paths)=}\")\n    \n    # 取得したパスの数を制限\n    if max_images_to_display is not None:\n        image_paths = image_paths[start_idx:start_idx+max_images_to_display]\n    \n    num_images = len(image_paths)\n    \n    if num_images == 0:\n        print(f\"not found path: '{search_path}'\")\n    else:\n        print(f\"show {num_images} images\")\n        \n        # 行数を計算\n        rows = math.ceil(num_images / cols)\n    \n        # FigureとAxes（サブプロット）を作成\n        # figsize は表示ウィンドウのサイズを調整します (幅, 高さ)\n        # 画像数や cols の値に合わせて適宜調整してください\n        plt.figure(figsize=(cols * 2.5, rows * 2.5)) # 1枚あたり約2.5x2.5インチとして計算\n    \n        # 各画像をサブプロットに表示\n        for i, img_path in enumerate(image_paths):\n            # サブプロットを指定 (行数, 列数, 現在のインデックス+1)\n            plt.subplot(rows, cols, i + 1)\n    \n            try:\n                # 画像を読み込み\n                img = Image.open(img_path).convert('RGB')\n    \n                # 画像を表示\n                plt.imshow(img)\n    \n                # タイトルを追加 (オプション)\n                # plt.title(f\"Image {i+1}\") # シンプルな番号\n                # ファイル名だけを表示したい場合 (パスから抽出)\n                # import os\n                plt.title(img_path[img_path.rfind('/')+1:], fontsize=8)\n    \n                # 軸の目盛りやラベルを非表示にして画像を大きく表示\n                plt.axis('off')\n    \n            except Exception as e:\n                print(f\"エラー: {img_path} の読み込みまたは表示に失敗しました - {e}\")\n                # エラーが発生した場所にテキストで表示することも可能\n                # plt.text(0.5, 0.5, 'Error', horizontalalignment='center', verticalalignment='center')\n                plt.axis('off') # エラー表示でも軸はオフに\n    \n        # サブプロット間のスペースを調整して、タイトルなどが重ならないようにする\n        plt.tight_layout()\n    \n        # ウィンドウを表示\n        plt.show()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-05-11T09:51:42.740000Z","iopub.execute_input":"2025-05-11T09:51:42.740356Z","iopub.status.idle":"2025-05-11T09:51:42.748687Z","shell.execute_reply.started":"2025-05-11T09:51:42.740327Z","shell.execute_reply":"2025-05-11T09:51:42.747518Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"show_train_image('tomo_003acc')","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-05-11T09:51:46.769238Z","iopub.execute_input":"2025-05-11T09:51:46.769633Z","iopub.status.idle":"2025-05-11T09:52:00.229958Z","shell.execute_reply.started":"2025-05-11T09:51:46.769600Z","shell.execute_reply":"2025-05-11T09:52:00.228577Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"# think\nfmmm ok Array shape (axis 0) is image counts...\n\nThis class number of motors is 0.\nmotor is nothing.\n\nNext, I look at tomo_00e047.\n\nMotor axis 0 is 169, so I examine around 169.","metadata":{}},{"cell_type":"code","source":"show_train_image('tomo_00e047', start_idx=160)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-05-11T09:52:00.231667Z","iopub.execute_input":"2025-05-11T09:52:00.232032Z","iopub.status.idle":"2025-05-11T09:52:05.382064Z","shell.execute_reply.started":"2025-05-11T09:52:00.231999Z","shell.execute_reply":"2025-05-11T09:52:05.380924Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"# think\nslice_0168.jpg contain motor?\n\nok, axis 1 and 2 is ... 546.0 603.0.","metadata":{}},{"cell_type":"code","source":"def show_motor(img_path: str, x: float, y: float) -> None:\n    \"\"\"\n    指定された画像を表示し、特定の座標を中心とした10pxの範囲を緑色の線で囲みます。\n\n    Args:\n        img_path (str): 表示する画像のパス。\n        x (float): 囲む領域の中心となるx座標。\n        y (float): 囲む領域の中心となるy座標。\n    \"\"\"\n\n    plt.figure(figsize=(10, 10)) # 1枚あたり約2.5x2.5インチとして計算\n\n    # 画像を読み込み\n    img = Image.open(img_path).convert('RGB')\n\n    # 画像を表示\n    plt.imshow(img)\n\n    # タイトルを追加 (オプション) - 元のコードの記述を維持\n    # import os # 必要ならここでインポートするか関数の外でインポート\n    plt.title(img_path[img_path.rfind('/')+1:], fontsize=8) # ファイル名だけを表示\n\n    # 軸の目盛りやラベルを非表示にして画像を大きく表示\n    plt.axis('off')\n\n    # 緑色の矩形を描画\n    # 中心 (x, y) からの10pxの範囲なので、左下は (x-10, y-10)、幅と高さは 20\n    # Rectangle((x, y), width, height, ...) の (x, y) は左下隅の座標\n    rect = patches.Rectangle(\n        (x - 10, y - 10),  # 矩形の左下隅の座標\n        20,                # 矩形の幅 (中心から左右に10pxずつなので合計20px)\n        20,                # 矩形の高さ (中心から上下に10pxずつなので合計20px)\n        linewidth=2,       # 線の太さ\n        edgecolor='green', # 線の色を緑に設定\n        facecolor='none'   # 塗りつぶしはなし\n    )\n\n    # 現在のaxes（描画領域）を取得し、矩形を追加\n    ax = plt.gca()\n    ax.add_patch(rect)\n\n    # サブプロット間のスペースを調整して、タイトルなどが重ならないようにする\n    plt.tight_layout()\n\n    # ウィンドウを表示\n    plt.show()\n\n# 使用例 (画像のパス 'your_image.jpg' と座標 150, 200 を適切に変更してください)\n# try:\n#     show_motor('your_image.jpg', 150, 200)\n# except FileNotFoundError:\n#     print(\"エラー: 'your_image.jpg' が見つかりません。適切な画像パスを指定してください。\")\n# except Exception as e:\n#     print(f\"エラーが発生しました: {e}\")","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-05-11T09:52:08.514194Z","iopub.execute_input":"2025-05-11T09:52:08.514595Z","iopub.status.idle":"2025-05-11T09:52:08.522299Z","shell.execute_reply.started":"2025-05-11T09:52:08.514563Z","shell.execute_reply":"2025-05-11T09:52:08.521168Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"show_motor(f\"{train_dir}/tomo_00e047/slice_0168.jpg\",546.0,603.0)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-05-11T09:52:09.279572Z","iopub.execute_input":"2025-05-11T09:52:09.279922Z","iopub.status.idle":"2025-05-11T09:52:10.076216Z","shell.execute_reply.started":"2025-05-11T09:52:09.279894Z","shell.execute_reply":"2025-05-11T09:52:10.075072Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"# think\nmmm? Where is motor.","metadata":{}},{"cell_type":"code","source":"show_motor(f\"{train_dir}/tomo_00e047/slice_0167.jpg\",546.0,603.0)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-05-11T09:52:15.573625Z","iopub.execute_input":"2025-05-11T09:52:15.573989Z","iopub.status.idle":"2025-05-11T09:52:16.380167Z","shell.execute_reply.started":"2025-05-11T09:52:15.573958Z","shell.execute_reply":"2025-05-11T09:52:16.378757Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"show_motor(f\"{train_dir}/tomo_00e047/slice_0169.jpg\",546.0,603.0)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-05-11T09:52:16.381811Z","iopub.execute_input":"2025-05-11T09:52:16.382182Z","iopub.status.idle":"2025-05-11T09:52:17.195298Z","shell.execute_reply.started":"2025-05-11T09:52:16.382146Z","shell.execute_reply":"2025-05-11T09:52:17.193708Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"# think\nSomething is wrong.","metadata":{}},{"cell_type":"code","source":"show_motor(f\"{train_dir}/tomo_00e047/slice_0168.jpg\",603.0,546.0)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-05-11T09:52:19.598439Z","iopub.execute_input":"2025-05-11T09:52:19.598768Z","iopub.status.idle":"2025-05-11T09:52:20.403792Z","shell.execute_reply.started":"2025-05-11T09:52:19.598743Z","shell.execute_reply":"2025-05-11T09:52:20.402578Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"# think\nOkey-Dokey. axis 1 is y axis(→). axis 2 is x axis（↓）.\n\nEven so, bacteria is very cute like a ramen man.\n\n![81oL+SOGSaL._SY425_.jpg](attachment:0de2dd90-bc6f-4c4e-9e63-525fcdd37511.jpg)\n\n(c) yudetamago/syueisya\n\n\nBut, does another image contain a motor?","metadata":{},"attachments":{"0de2dd90-bc6f-4c4e-9e63-525fcdd37511.jpg":{"image/jpeg":"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"}}},{"cell_type":"code","source":"print(\"slice_0168.jpg-1(axis 0)\")\nshow_motor(f\"{train_dir}/tomo_00e047/slice_0167.jpg\",603.0,546.0)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-05-11T09:58:28.424845Z","iopub.execute_input":"2025-05-11T09:58:28.425186Z","iopub.status.idle":"2025-05-11T09:58:29.247253Z","shell.execute_reply.started":"2025-05-11T09:58:28.425158Z","shell.execute_reply":"2025-05-11T09:58:29.245503Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"print(\"slice_0168.jpg-2(axis 0)\")\nshow_motor(f\"{train_dir}/tomo_00e047/slice_0166.jpg\",603.0,546.0)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-05-11T09:58:23.450796Z","iopub.execute_input":"2025-05-11T09:58:23.451120Z","iopub.status.idle":"2025-05-11T09:58:24.262554Z","shell.execute_reply.started":"2025-05-11T09:58:23.451097Z","shell.execute_reply":"2025-05-11T09:58:24.260914Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"print(\"slice_0168.jpg-3(axis 0)\")\nshow_motor(f\"{train_dir}/tomo_00e047/slice_0165.jpg\",603.0,546.0)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-05-11T09:58:43.828069Z","iopub.execute_input":"2025-05-11T09:58:43.828421Z","iopub.status.idle":"2025-05-11T09:58:44.643029Z","shell.execute_reply.started":"2025-05-11T09:58:43.828369Z","shell.execute_reply":"2025-05-11T09:58:44.641845Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"print(\"slice_0168.jpg-4(axis 0)\")\nshow_motor(f\"{train_dir}/tomo_00e047/slice_0164.jpg\",603.0,546.0)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-05-11T09:58:59.605933Z","iopub.execute_input":"2025-05-11T09:58:59.606400Z","iopub.status.idle":"2025-05-11T09:59:00.433326Z","shell.execute_reply.started":"2025-05-11T09:58:59.606341Z","shell.execute_reply":"2025-05-11T09:59:00.431880Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"print(\"slice_0168.jpg-5(axis 0)\")\nshow_motor(f\"{train_dir}/tomo_00e047/slice_0164.jpg\",603.0,546.0)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-05-11T09:59:14.505127Z","iopub.execute_input":"2025-05-11T09:59:14.505553Z","iopub.status.idle":"2025-05-11T09:59:15.340370Z","shell.execute_reply.started":"2025-05-11T09:59:14.505519Z","shell.execute_reply":"2025-05-11T09:59:15.338967Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"print(\"slice_0168.jpg+1(axis 0)\")\nshow_motor(f\"{train_dir}/tomo_00e047/slice_0169.jpg\",603.0,546.0)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-05-11T09:59:46.249779Z","iopub.execute_input":"2025-05-11T09:59:46.250105Z","iopub.status.idle":"2025-05-11T09:59:47.057060Z","shell.execute_reply.started":"2025-05-11T09:59:46.250082Z","shell.execute_reply":"2025-05-11T09:59:47.055787Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"print(\"slice_0168.jpg+2(axis 0)\")\nshow_motor(f\"{train_dir}/tomo_00e047/slice_0170.jpg\",603.0,546.0)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-05-11T09:59:55.584921Z","iopub.execute_input":"2025-05-11T09:59:55.585245Z","iopub.status.idle":"2025-05-11T09:59:56.391002Z","shell.execute_reply.started":"2025-05-11T09:59:55.585221Z","shell.execute_reply":"2025-05-11T09:59:56.389663Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"# parse data\n\nThank you for https://www.kaggle.com/code/andrewjdarley/parse-data\n\nFmfm, I parse train labels to YOLO style.\n\nBut, what is TRUST and Normalization process?\n\n...searching\n\nTRUST: When extracting 2D slices from a tomogram, which is 3D data, this setting is used to include not only the central Z standard of the label, but also slices above and below it in the dataset.\n\nNormalization: The image data of each slice is clipped at the 2nd and 98th percentiles, and then linearly scaled to the range of 0 to 255.\n\n...but TRUST and Normalize percentile is not necesarily correct. So Let's make it changeable.\n","metadata":{}},{"cell_type":"code","source":"# Define constants\nTRUST = 4  # Number of slices above and below center slice (total 2*TRUST + 1 slices)\nSLICE_PERCENTILE = 2\nBOX_SIZE = 24  # Bounding box size for annotations (in pixels)\nTRAIN_SPLIT = 0.8  # 80% for training, 20% for validation","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-05-11T10:01:23.564861Z","iopub.execute_input":"2025-05-11T10:01:23.565193Z","iopub.status.idle":"2025-05-11T10:01:23.570129Z","shell.execute_reply.started":"2025-05-11T10:01:23.565170Z","shell.execute_reply":"2025-05-11T10:01:23.568812Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Image processing functions\ndef normalize_slice(slice_data):\n    \"\"\"\n    Normalize slice data using 2nd and 98th percentiles\n    \"\"\"\n    # Calculate percentiles\n    p_small = np.percentile(slice_data, SLICE_PERCENTILE)\n    p_large = np.percentile(slice_data, 100-SLICE_PERCENTILE)\n    \n    # Clip the data to the percentile range\n    clipped_data = np.clip(slice_data, p_small, p_large)\n    \n    # Normalize to [0, 255] range\n    normalized = 255 * (clipped_data - p_small) / (p_large - p_small)\n    \n    return np.uint8(normalized)\n\ndef prepare_yolo_dataset(trust=TRUST, train_split=TRAIN_SPLIT):\n    \"\"\"\n    Extract slices containing motors from tomograms and save to YOLO structure with annotations\n    \"\"\"\n    # Load the labels CSV\n    labels_df = pd.read_csv(os.path.join(data_path, \"train_labels.csv\"))\n    \n    # Count total number of motors\n    total_motors = labels_df['Number of motors'].sum()\n    print(f\"Total number of motors in the dataset: {total_motors}\")\n    \n    # Get unique tomograms that have motors\n    tomo_df = labels_df[labels_df['Number of motors'] > 0].copy()\n    unique_tomos = tomo_df['tomo_id'].unique()\n    \n    print(f\"Found {len(unique_tomos)} unique tomograms with motors\")\n    \n    # Perform the train-val split at the tomogram level (not motor level)\n    # This ensures all slices from a single tomogram go to either train or val\n    np.random.shuffle(unique_tomos)  # Shuffle the tomograms\n    split_idx = int(len(unique_tomos) * train_split)\n    train_tomos = unique_tomos[:split_idx]\n    val_tomos = unique_tomos[split_idx:]\n    \n    print(f\"Split: {len(train_tomos)} tomograms for training, {len(val_tomos)} tomograms for validation\")\n    \n    # Function to process a set of tomograms\n    def process_tomogram_set(tomogram_ids, images_dir, labels_dir, set_name):\n        motor_counts = []\n        for tomo_id in tomogram_ids:\n            # Get all motors for this tomogram\n            tomo_motors = labels_df[labels_df['tomo_id'] == tomo_id]\n            for _, motor in tomo_motors.iterrows():\n                if pd.isna(motor['Motor axis 0']):\n                    continue\n                motor_counts.append(\n                    (tomo_id, \n                     int(motor['Motor axis 0']), \n                     int(motor['Motor axis 1']), \n                     int(motor['Motor axis 2']),\n                     int(motor['Array shape (axis 0)']))\n                )\n        \n        print(f\"Will process approximately {len(motor_counts) * (2 * trust + 1)} slices for {set_name}\")\n        \n        # Process each motor\n        processed_slices = 0\n        \n        for tomo_id, z_center, y_center, x_center, z_max in tqdm(motor_counts, desc=f\"Processing {set_name} motors\"):\n            # Calculate range of slices to include\n            z_min = max(0, z_center - trust)\n            z_max = min(z_max - 1, z_center + trust)\n            \n            # Process each slice in the range\n            for z in range(z_min, z_max + 1):\n                # Create slice filename\n                slice_filename = f\"slice_{z:04d}.jpg\"\n                \n                # Source path for the slice\n                src_path = os.path.join(train_dir, tomo_id, slice_filename)\n                \n                if not os.path.exists(src_path):\n                    print(f\"Warning: {src_path} does not exist, skipping.\")\n                    continue\n                \n                # Load and normalize the slice\n                img = Image.open(src_path)\n                img_array = np.array(img)\n                \n                # Normalize the image\n                normalized_img = normalize_slice(img_array)\n                \n                # Create destination filename (with unique identifier)\n                dest_filename = f\"{tomo_id}_z{z:04d}_y{y_center:04d}_x{x_center:04d}.jpg\"\n                dest_path = os.path.join(images_dir, dest_filename)\n                \n                # Save the normalized image\n                Image.fromarray(normalized_img).save(dest_path)\n                \n                # Get image dimensions\n                img_width, img_height = img.size\n                \n                # Create YOLO format label\n                # YOLO format: <class> <x_center> <y_center> <width> <height>\n                # Values are normalized to [0, 1]\n                x_center_norm = x_center / img_width\n                y_center_norm = y_center / img_height\n                box_width_norm = BOX_SIZE / img_width\n                box_height_norm = BOX_SIZE / img_height\n                \n                # Write label file\n                label_path = os.path.join(labels_dir, dest_filename.replace('.jpg', '.txt'))\n                with open(label_path, 'w') as f:\n                    f.write(f\"0 {x_center_norm} {y_center_norm} {box_width_norm} {box_height_norm}\\n\")\n                \n                processed_slices += 1\n        \n        return processed_slices, len(motor_counts)\n    \n    # Process training tomograms\n    train_slices, train_motors = process_tomogram_set(train_tomos, yolo_images_train, yolo_labels_train, \"training\")\n    \n    # Process validation tomograms\n    val_slices, val_motors = process_tomogram_set(val_tomos, yolo_images_val, yolo_labels_val, \"validation\")\n    \n    # Create YAML configuration file for YOLO\n    yaml_content = {\n        'path': yolo_dataset_dir,\n        'train': 'images/train',\n        'val': 'images/val',\n        'names': {0: 'motor'}\n    }\n    \n    with open(os.path.join(yolo_dataset_dir, 'dataset.yaml'), 'w') as f:\n        yaml.dump(yaml_content, f, default_flow_style=False)\n    \n    print(f\"\\nProcessing Summary:\")\n    print(f\"- Train set: {len(train_tomos)} tomograms, {train_motors} motors, {train_slices} slices\")\n    print(f\"- Validation set: {len(val_tomos)} tomograms, {val_motors} motors, {val_slices} slices\")\n    print(f\"- Total: {len(train_tomos) + len(val_tomos)} tomograms, {train_motors + val_motors} motors, {train_slices + val_slices} slices\")\n    \n    # Return summary info\n    return {\n        \"dataset_dir\": yolo_dataset_dir,\n        \"yaml_path\": os.path.join(yolo_dataset_dir, 'dataset.yaml'),\n        \"train_tomograms\": len(train_tomos),\n        \"val_tomograms\": len(val_tomos),\n        \"train_motors\": train_motors,\n        \"val_motors\": val_motors,\n        \"train_slices\": train_slices,\n        \"val_slices\": val_slices\n    }\n\n# Run the preprocessing\nsummary = prepare_yolo_dataset(TRUST)\nprint(f\"\\nPreprocessing Complete:\")\nprint(f\"- Training data: {summary['train_tomograms']} tomograms, {summary['train_motors']} motors, {summary['train_slices']} slices\")\nprint(f\"- Validation data: {summary['val_tomograms']} tomograms, {summary['val_motors']} motors, {summary['val_slices']} slices\")\nprint(f\"- Dataset directory: {summary['dataset_dir']}\")\nprint(f\"- YAML configuration: {summary['yaml_path']}\")\nprint(f\"\\nReady for YOLO training!\")","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-05-11T10:01:24.644520Z","iopub.execute_input":"2025-05-11T10:01:24.644928Z","iopub.status.idle":"2025-05-11T10:04:24.996596Z","shell.execute_reply.started":"2025-05-11T10:01:24.644895Z","shell.execute_reply":"2025-05-11T10:04:24.995655Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"print(f\"TRUST: {TRUST}\")\nprint(f\"SLICE_PERCENTILE: {SLICE_PERCENTILE}\")\nprint(f\"BOX_SIZE: {BOX_SIZE}\")\nprint(f\"TRAIN_SPLIT: {TRAIN_SPLIT}\")\n\n# Python側でf-stringを使って最終的なパス文字列を組み立てる\noutput_path = f\"byu_yolo_dataset_{TRUST=}_{SLICE_PERCENTILE=}_{BOX_SIZE=}_{TRAIN_SPLIT=}\"\n\n# 組み立てた一つのPython変数をシェルコマンドで使う\n# この場合、$output_path が Pythonの変数 output_path の値に置き換わります\n!echo \"$output_path\".tar.gz\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-05-11T10:10:44.572739Z","iopub.execute_input":"2025-05-11T10:10:44.573137Z","iopub.status.idle":"2025-05-11T10:10:44.703661Z","shell.execute_reply.started":"2025-05-11T10:10:44.573102Z","shell.execute_reply":"2025-05-11T10:10:44.702047Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"!tar -czvf \"$output_path\".tar.gz -C yolo_dataset .","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-05-11T10:11:15.716211Z","iopub.execute_input":"2025-05-11T10:11:15.716641Z","iopub.status.idle":"2025-05-11T10:14:00.408192Z","shell.execute_reply.started":"2025-05-11T10:11:15.716593Z","shell.execute_reply":"2025-05-11T10:14:00.406377Z"},"collapsed":true,"jupyter":{"outputs_hidden":true}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"# Download\nLet's download dataset or push dataset by kagglehub.","metadata":{}},{"cell_type":"markdown","source":"# visualize data\n\nthnx https://www.kaggle.com/code/andrewjdarley/visualize-data","metadata":{}},{"cell_type":"code","source":"# if you execute sequencely.\n\nimages_train_dir = \"/kaggle/working/yolo_dataset/images/train/\"\nlabels_train_dir = \"/kaggle/working/yolo_dataset/labels/train/\"\n\n# # else\n# images_train_dir = \"/kaggle/input/parse-data/yolo_dataset/images/train/\"\n# labels_train_dir = \"/kaggle/input/parse-data/yolo_dataset/labels/train/\"\n\n# BOX_SIZE = 24","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-05-11T10:22:32.575510Z","iopub.execute_input":"2025-05-11T10:22:32.576333Z","iopub.status.idle":"2025-05-11T10:22:32.582525Z","shell.execute_reply.started":"2025-05-11T10:22:32.576283Z","shell.execute_reply":"2025-05-11T10:22:32.581371Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import random\nimport matplotlib.pyplot as plt\nfrom PIL import Image, ImageDraw\nimport os\nimport numpy as np\nimport glob\n\n# Define base_dir - this was missing in the original code\n# In Kaggle, we can use the working directory as base or remove it completely\n# since we're using absolute paths\nbase_dir = \"/kaggle/working\"  # or simply use \"\" if using absolute paths\n\n\ndef visualize_random_training_samples(num_samples=4):\n    \"\"\"\n    Visualize random training samples with YOLO annotations\n    \n    Args:\n        num_samples (int): Number of random images to display\n    \"\"\"\n    # Get all image files from the train directory\n    image_files = []\n    for ext in ['*.jpg', '*.jpeg', '*.png']:\n        image_files.extend(glob.glob(os.path.join(images_train_dir, \"**\", ext), recursive=True))\n    \n    # Make sure we have enough images\n    if len(image_files) == 0:\n        print(\"No image files found in the train directory!\")\n        return\n        \n    num_samples = min(num_samples, len(image_files))\n    \n    # Select random images\n    random_images = random.sample(image_files, num_samples)\n    \n    # Create a figure with subplots\n    rows = int(np.ceil(num_samples / 2))\n    cols = min(num_samples, 2)\n    fig, axes = plt.subplots(rows, cols, figsize=(14, 5 * rows))\n    \n    # Handle the case of a single subplot\n    if num_samples == 1:\n        axes = np.array([axes])\n    \n    # Flatten axes array for easy indexing\n    axes = axes.flatten()\n    \n    # Process each selected image\n    for i, img_path in enumerate(random_images):\n        try:\n            # Get corresponding label file\n            # YOLO labels have same name but .txt extension instead of image extension\n            relative_path = os.path.relpath(img_path, images_train_dir)\n            label_path = os.path.join(labels_train_dir, os.path.splitext(relative_path)[0] + '.txt')\n            \n            # Load the image\n            img = Image.open(img_path)\n            img_width, img_height = img.size\n            \n            # Normalize image using percentiles for better visualization\n            img_array = np.array(img)\n            p2 = np.percentile(img_array, 2)\n            p98 = np.percentile(img_array, 98)\n            normalized = np.clip(img_array, p2, p98)\n            normalized = 255 * (normalized - p2) / (p98 - p2)\n            img_normalized = Image.fromarray(np.uint8(normalized))\n            \n            # Convert image to RGB for colored box\n            img_rgb = img_normalized.convert('RGB')\n            \n            # Create a transparent overlay\n            overlay = Image.new('RGBA', img_rgb.size, (0, 0, 0, 0))\n            draw = ImageDraw.Draw(overlay)\n            \n            # Load YOLO format annotations if they exist\n            annotations = []\n            if os.path.exists(label_path):\n                with open(label_path, 'r') as f:\n                    for line in f:\n                        # YOLO format: class x_center y_center width height\n                        # All values are normalized from 0 to 1\n                        values = line.strip().split()\n                        class_id = int(values[0])\n                        x_center = float(values[1]) * img_width\n                        y_center = float(values[2]) * img_height\n                        width = float(values[3]) * img_width\n                        height = float(values[4]) * img_height\n                        \n                        annotations.append({\n                            'class_id': class_id,\n                            'x_center': x_center,\n                            'y_center': y_center,\n                            'width': width,\n                            'height': height\n                        })\n            \n            # Draw all annotations\n            for ann in annotations:\n                x_center = ann['x_center']\n                y_center = ann['y_center']\n                width = ann['width']\n                height = ann['height']\n                \n                # Calculate bounding box coordinates\n                x1 = max(0, int(x_center - width/2))\n                y1 = max(0, int(y_center - height/2))\n                x2 = min(img_width, int(x_center + width/2))\n                y2 = min(img_height, int(y_center + height/2))\n                \n                # Draw semi-transparent red rectangle\n                draw.rectangle([x1, y1, x2, y2], fill=(255, 0, 0, 64), outline=(255, 0, 0, 200))\n                \n                # Draw label\n                label_text = f\"Class {ann['class_id']}\"\n                draw.text((x1, y1-10), label_text, fill=(255, 0, 0, 255))\n            \n            # If no annotations found, indicate this\n            if not annotations:\n                draw.text((10, 10), \"No annotations found\", fill=(255, 0, 0, 255))\n            \n            # Composite the overlay onto the original image\n            img_rgb = Image.alpha_composite(img_rgb.convert('RGBA'), overlay).convert('RGB')\n            \n            # Display the image with annotations\n            axes[i].imshow(np.array(img_rgb))\n            img_name = os.path.basename(img_path)\n            axes[i].set_title(f\"Image: {img_name}\\nAnnotations: {len(annotations)}\")\n            axes[i].axis('on')\n            \n        except Exception as e:\n            print(f\"Error processing image {img_path}: {e}\")\n            axes[i].text(0.5, 0.5, f\"Error loading image: {os.path.basename(img_path)}\", \n                       horizontalalignment='center', verticalalignment='center')\n            axes[i].axis('off')\n    \n    # Handle extra subplots if any\n    for j in range(i + 1, len(axes)):\n        axes[j].axis('off')\n    \n    plt.tight_layout()\n    plt.show()\n    \n    # Print summary\n    print(f\"Displayed {num_samples} random images with YOLO annotations\")\n\n# Run the visualization\nvisualize_random_training_samples(4)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-05-11T10:22:38.880134Z","iopub.execute_input":"2025-05-11T10:22:38.880563Z","iopub.status.idle":"2025-05-11T10:22:40.869108Z","shell.execute_reply.started":"2025-05-11T10:22:38.880527Z","shell.execute_reply":"2025-05-11T10:22:40.867941Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"# think\nOk, I complete preparing dataset.\nLet's test training YOLO.","metadata":{}},{"cell_type":"code","source":"","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"","metadata":{"trusted":true},"outputs":[],"execution_count":null}]}