sam-cell-seg について
SAMによる細胞や物体のセグメンテーション、マスク処理、ポリゴン変換に取り組むための手順を示すスキルです。コマンドラインとCSV座標データを用いる推論パイプラインの構築・検証を支援します。
主な機能
- 01SAMセグメンテーション手順の計画
- 02マスクのポリゴン変換
- 03CSV座標データの処理
- 04コマンドライン引数要件の確認
- 05出力形式と指標の検証
活用シーン
- 01顕微鏡画像の細胞分割パイプライン構築
- 02分割マスクの座標への変換
- 03コマンドライン推論出力の検証
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ letta-ai/ skills --skill sam-cell-segインストール後、Claude Code で/sam-cell-segを入力して読み込まれたか確認します。
詳細
SAM 細胞セグメンテーションスキル
このスキルでは、SAM(Segment Anything Model)を用いた細胞セグメンテーション、マスク処理、ポリゴン変換パイプラインに関するタスクのガイダンスを提供します。
タスクの特徴
このスキルは、以下のようなタスクに適用できます。
- MobileSAM または SAM モデルを用いた画像セグメンテーション
- バイナリマスクからポリゴン/ポリライン表現への変換
- 座標データを含む CSV ファイルの処理
- ディープラーニング推論パイプライン用コマンドラインツールの構築
- 顕微鏡画像における細胞または物体のセグメンテーション
実装前の重要な手順
1. インターフェース要件の確認
コードを書く前に、インターフェース要件を正確に確認してください。
-
スクリプトの呼び出し方法を確認する:
- テストファイルまたは評価ハーネスを読み、想定される引数の形式を把握します
- 引数を位置引数にするか、キーワード引数(
--arg_name)にするかを判断します - テストフレームワークが想定する引数名を正確に確認します
-
出力形式の仕様を確認する:
- 入力ファイルの形式を確認し、出力形式を正確に合わせます
- データ型(リストかタプルか、文字列か数値か)に注意します
- CSV 出力の列名、順序、区切り文字を確認します
-
評価基準を理解する:
- 使用される指標(IoU、精度など)とそのしきい値を特定します
- 合格/不合格の条件を理解します
2. 環境に関する前提
- 指定されたパッケージはテスト環境で利用できるものとします
- 環境のセットアップやパッケージのインストールに時間をかけすぎないでください
- パッケージのインストールに失敗したり、タイムアウトしたりした場合は、パッケージが存在する前提でコード開発を進めます
- 環境のデバッグよりコードの正しさを優先します
実装方法
引数解析のパターン
ML パイプライン用の CLI ツールを構築するときは、明示的なフラグを使ったキーワード引数を使用します。
import argparse
def parse_args():
parser = argparse.ArgumentParser(description='Process masks with SAM')
# Use keyword arguments (--flag format), not positional
parser.add_argument('--weights_path', type=str, required=True,
help='Path to model weights')
parser.add_argument('--csv_path', type=str, required=True,
help='Path to input CSV')
parser.add_argument('--rgb_path', type=str, required=True,
help='Path to RGB image')
parser.add_argument('--output_path', type=str, required=True,
help='Path for output CSV')
return parser.parse_args()
データ型の一貫性
パイプライン全体を通じてデータ型を一貫させます。
# When processing coordinates, maintain list format (not tuples)
def mask_to_polygon(mask):
# ... processing logic ...
# Return coordinates as lists, not tuples
return [[int(x), int(y)] for x, y in coordinates]
# When saving to CSV, verify format
def save_coordinates(coords, output_path):
# Ensure coordinates are stored as lists
formatted_coords = [list(c) if isinstance(c, tuple) else c for c in coords]
# ... save logic ...
SAM/MobileSAM の統合パターン
def load_sam_model(weights_path, device='cuda'):
"""Load SAM model with proper device handling."""
# Check device availability
if device == 'cuda' and not torch.cuda.is_available():
device = 'cpu'
# Load model
model = sam_model_registry[model_type](checkpoint=weights_path)
model.to(device)
model.eval()
return model, device
def refine_mask_with_sam(sam_model, image, initial_mask, device):
"""Use SAM to refine an initial mask."""
predictor = SamPredictor(sam_model)
predictor.set_image(image)
# Get bounding box or point prompts from initial mask
# ... prompt extraction logic ...
masks, scores, _ = predictor.predict(
point_coords=point_coords,
point_labels=point_labels,
box=box,
multimask_output=True
)
# Select best mask based on IoU with initial mask or score
best_mask = select_best_mask(masks, scores, initial_mask)
return best_mask
マスクからポリゴンへの変換
import cv2
import numpy as np
def mask_to_polygon(binary_mask, simplify_tolerance=1.0):
"""Convert binary mask to polygon coordinates."""
# Ensure mask is binary uint8
mask = (binary_mask > 0).astype(np.uint8) * 255
# Find contours
contours, _ = cv2.findContours(mask, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
if not contours:
return []
# Get largest contour
largest_contour = max(contours, key=cv2.contourArea)
# Simplify contour
epsilon = simplify_tolerance * cv2.arcLength(largest_contour, True)
simplified = cv2.approxPolyDP(largest_contour, epsilon, True)
# Convert to list format (not tuples)
polygon = [[int(pt[0][0]), int(pt[0][1])] for pt in simplified]
return polygon
検証チェックリスト
提出前
-
インターフェースの検証:
-
python script.py --helpを実行し、引数解析が機能することを確認します - 引数名がテストの想定と完全に一致することを確認します
- キーワード引数と位置引数のどちらの形式かを確認します
-
-
出力形式の検証:
- 出力 CSV の構造を入力 CSV の構造と比較します
- 座標データ型がタプルではなくリストであることを確認します
- 想定されるすべての行が出力に含まれていることを確認します
- 列名と順序を検証します
-
エンドツーエンドテスト:
- サンプルデータでパイプライン全体を実行します
- 出力ファイルが作成され、適切な形式になっていることを確認します
- すべての入力行に対応する出力が生成されることを確認します
-
品質指標:
- 精緻化したマスクと期待される出力の IoU を計算します
- 指標がしきい値要件を満たしていることを確認します(例:IoU > 0.5)
コードレビューのポイント
- 引数パーサー:位置引数ではなく、
--flag形式を使用している - データ型:座標はタプルではなくリストとして保存されている
- エラー処理:エッジケース(空のマスク、ファイルの欠落)を適切に処理する
- デバイス処理:CUDA/CPU の適切なフォールバックロジックを備えている
よくある落とし穴
1. 引数形式の不一致
問題:テストがキーワード引数を想定しているのに、位置引数を使用している。
検出方法:「unrecognized arguments」などのエラーが発生し、スクリプトが失敗します。
解決策:argparse を実装する前に、必ずテストの呼び出し形式を確認します。
2. データ型の不一致
問題:リストが想定されているのに、座標をタプルとして保存している。
検出方法:座標形式または JSON シリアライズに関連するテストが失敗します。
解決策:保存前に明示的にリストへ変換します:[list(coord) for coord in coords]
3. 処理の不完全
問題:入力行のすべてが出力に現れません。
検出方法:入力と出力の行数が一致しません。
解決策:ループですべての行を処理していることを確認し、進行状況を追跡するログを追加します。
4. 環境デバッグの罠
問題:タイムアウトが発生しているにもかかわらず、パッケージのインストールに過剰な時間を費やしてしまいます。
検出方法:インストールに何度も失敗します。
解決策:テスト環境を信頼し、コードの正しさに注力します。ローカルでパッケージのインストールに失敗した場合は、それらが存在すると仮定して作業を進めます。
5. 早すぎる完了宣言
問題:エンドツーエンドで検証せずに、タスクが完了したと宣言します。
検出方法:テスト評価の段階で初めて、根本的なエラーが見つかります。
解決策:完了を宣言する前に、必ずテスト引数を指定して実際のコマンドを実行します。
6. ファイルの読み取りが不完全
問題:ファイルの内容を最後まで読まず、重要なコード部分を見落とします。
検出方法:読み取っていない箇所にある明らかなエラーが、コードレビューで見逃されます。
解決策:ファイルの出力が途中で切れた場合は、分割して読み取るか、offset/limit パラメーターを使用します。
テスト戦略
単体テストの優先順位
- 引数の解析:CLI インターフェースが想定と一致していることを確認します
- 入出力形式:データがパイプラインを通じて正しく流れることを確認します
- コア機能:マスク処理とポリゴン変換をテストします
- 統合:エンドツーエンドのパイプラインテスト
最小限のテスト
# Quick sanity check before full test suite
import subprocess
import sys
def test_cli_interface():
"""Verify script accepts expected arguments."""
result = subprocess.run(
[sys.executable, 'script.py', '--help'],
capture_output=True,
text=True
)
assert result.returncode == 0
assert '--weights_path' in result.stdout
assert '--csv_path' in result.stdout
assert '--rgb_path' in result.stdout
assert '--output_path' in result.stdout
タスクの実行順序
- テストファイルまたは評価ハーネスを読み、インターフェースの要件を把握します
- 正確な引数形式と出力形式の仕様を特定します
- 見つかった要件に合うように引数の解析を実装します
- コア機能(SAM の読み込み、マスク処理、ポリゴン変換)を実装します
--helpフラグでインターフェースを確認します- サンプルデータを使ってエンドツーエンドテストを実行します
- 出力形式が仕様に正確に一致することを確認します
- すべての品質指標がしきい値を満たしていることを確認します