システム仕様書
Card Grader TCG鑑定士 v0.1.0
1. システム概要
| システム名 | Card Grader TCG鑑定士 |
| バージョン | 0.1.0 |
| 目的 | TCGカードの画像を自動解析し、PSA基準に準じた1-10スケールのグレーディングスコアを算出する |
| 対象カード | スタンダード (63x88mm): ポケモンカード / MTG / ワンピースカード 等 スモール (59x86mm): 遊戯王 等 |
| 対応画像形式 | JPEG / PNG / WebP (最大20MB) |
| 推奨解像度 | 1000 x 1400px 以上 (処理時は長辺1200pxにリサイズ) |
2. システム構成
| レイヤー | 技術 | ホスティング |
|---|---|---|
| フロントエンド | Next.js 14 (App Router) + TypeScript + Tailwind CSS | Vercel |
| バックエンド API | Python 3.12 + FastAPI | Render (Free) |
| 画像処理 | OpenCV 4.10 + NumPy + scikit-image | - |
| データ保存 | インメモリ (MVP) | - |
[ブラウザ] ──HTTPS──▶ [Vercel / Next.js]
│
POST /api/v1/grade (multipart)
│
▼
[Render / FastAPI]
│
┌─────────┼─────────┐
▼ ▼ ▼
[前処理] [4分析エンジン] [スコア算出]
カード検出 並列実行 重み付け合計
傾き補正 PSA変換3. 画像処理パイプライン
3.1 前処理 (preprocessing.py)
入力画像のリサイズ: 長辺1200pxを超える画像は処理前にリサイズ (INTER_AREA補間)
カード領域検出: Canny エッジ検出 → 輪郭抽出 → 面積最大の4角形を選択
傾き補正: 検出した4点からホモグラフィ変換で正面化 (cv2.getPerspectiveTransform + warpPerspective)
カードタイプ推定: アスペクト比からスタンダード (0.716) / スモール (0.686) を判定
正面化後のリサイズ: カード画像は長辺800pxにリサイズして分析モジュールに渡す
4. センタリング分析 (centering.py)
カード外縁と内部印刷領域の中心ズレから、印刷の対称性を評価する。 撮影位置に依存しないよう、外枠と内枠の相対的な位置関係で判定する。
検出手法 (3手法のアンサンブル)
| 手法 | アルゴリズム |
|---|---|
| ボーダー色分離 | HSV色空間でカード四辺のサンプリング → ボーダー色のマスク生成 → 反転して内部領域のバウンディングボックスを取得 |
| エッジ密度勾配 | Canny エッジ検出 → 四辺からスキャンしてエッジ密度が急増する位置を内部枠の境界とする |
| 輪郭ベース矩形検出 | 膨張エッジ → 輪郭検出 → カード面積の30〜90%かつ矩形度が高い輪郭を内部枠とする |
3手法の結果のメディアンを最終的な内部枠として採用し、安定性を確保。
スコアリング基準 (PSA準拠)
| スコア | 許容比率 (大きい側) |
|---|---|
| 10 | 52%以内 |
| 9.5 | 55%以内 |
| 9.0 | 57%以内 |
| 8.0 | 62%以内 |
| 7.0 | 67%以内 |
| 6.0 | 73%以内 |
| 3.0 | 80%超 |
5. 表面傷検出 (surface.py)
| 検出対象 | アルゴリズム | 深刻度判定 |
|---|---|---|
| スクラッチ (線状傷) | ガウシアンブラーとの差分 → 閾値処理 → 線状構造強調 (方向カーネル) → アスペクト比3以上の輪郭 | 面積 <200: minor / <1000: major / 1000+: critical |
| ホワイトニング (白化) | カード端10%の領域で明度230以上のピクセル割合を計測 | 15〜30%: minor / 30%+: major |
| 折れ・クリース | ラプラシアンフィルタ → Hough変換で長い直線検出 (カード長辺の15%以上) | 長さ30%+: major / 30%未満: minor |
| 角ダメージ | 四角10%領域のエッジ密度 + テクスチャ標準偏差で異常度算出 | スコア0.3〜0.6: minor / 0.6+: major |
スコア算出: 欠陥なし=10.0、minor=-0.5、major=-1.5、critical=-3.0 のペナルティ方式 (0.5刻み、下限1.0)
6. 色・印刷分析 (color.py)
| 分析項目 | アルゴリズム | 出力 |
|---|---|---|
| 色褪せ検出 | HSV彩度チャネルの平均・標準偏差 + 明度チャネルの分布 | 0.0 (なし) 〜 1.0 (完全に色褪せ) |
| インク均一性 | 6x8グリッドに分割 → 隣接セルの彩度平均の差分を計測 | 0.0 (不均一) 〜 1.0 (均一) |
| 彩度スコア | HSV彩度チャネルの平均と分散から品質評価 | 0.0 (低品質) 〜 1.0 (高品質) |
| ホロ/フォイル判定 | 色相のばらつき (std>40) + 高彩度ピクセル比率 (30%+) + 明度変動 (std>40) | true / false |
| 印刷ズレ検出 | RGB各チャネルのCannyエッジ位置の差異を計測 | 0.0 (なし) 〜 1.0 (大きなズレ) |
7. エッジ・角分析 (edges.py)
| 分析項目 | アルゴリズム |
|---|---|
| エッジ直線性 | 四辺5%領域のCannyエッジ位置の標準偏差 → 小さいほど直線 (0.0〜1.0) |
| 角の丸み均一性 | 四角8%領域のエッジ点の放射距離分布 → 変動係数で均一性評価 (0.0〜1.0) |
| 角ダメージ検出 | ラプラシアン標準偏差 + エッジ密度 + 明度標準偏差の複合スコア |
スコア算出: エッジ直線性 x 40% + 角均一性 x 60% - 角ダメージペナルティ (minor: -0.5 / major: -1.5)
8. 総合グレーディング (grading.py)
重み付け
| 項目 | 重み | 根拠 |
|---|---|---|
| センタリング | 20% | 製造由来の問題で個体差が大きい |
| 表面状態 | 35% | 最も視覚的に目立つ欠陥 |
| 色・印刷 | 20% | 経年劣化の主要指標 |
| エッジ・角 | 25% | 使用・保管状態の主要指標 |
信頼度算出
- カード輪郭の検出失敗: x 0.7
- 画像解像度 500px未満: x 0.6 / 800px未満: x 0.8
- サブスコアの標準偏差 3.0超: x 0.8
9. API仕様
| メソッド | パス | 説明 |
|---|---|---|
| POST | /api/v1/grade | カード鑑定を実行 (multipart/form-data) |
| GET | /api/v1/grade/{id} | 鑑定結果を取得 |
| GET | /api/v1/history | 鑑定履歴一覧 |
| DELETE | /api/v1/history/{id} | 鑑定結果を削除 |
| GET | /health | ヘルスチェック |
POST /api/v1/grade
// リクエスト (multipart/form-data)
front_image: File // 必須。カード表面の画像
card_type: string // "standard" | "small" (デフォルト: "standard")
// レスポンス
{
"id": "uuid",
"overall_grade": 8.5, // 1.0 - 10.0 (0.5刻み)
"confidence": 0.87, // 0.0 - 1.0
"card_image": "base64...", // 正面化されたカード画像
"card_type": "standard",
"sub_grades": {
"centering": { "score": 9.0, "detail": { ... } },
"surface": { "score": 8.0, "detail": { ... } },
"color_print": { "score": 9.0, "detail": { ... } },
"edges_corners": { "score": 8.0, "detail": { ... } }
},
"overlay_images": {
"centering": "base64...",
"surface_defects": "base64...",
"color_analysis": "base64...",
"edges_corners": "base64..."
},
"created_at": "2026-03-29T00:00:00+00:00"
}10. 制約事項・既知の制限
PSA公式鑑定との差異
本システムは画像処理ベースの自動分析であり、PSA公式鑑定の結果を保証するものではありません。
表面のみの分析
現在は表面(おもて面)の画像のみを分析対象としています。裏面分析は未対応です。
厚み分析の制限
単一画像からカードの厚みを正確に測定することはできません。側面画像による分析は今後の課題です。
ホロ・フォイルカードの精度
ホログラフィックカードは光の反射が傷として誤検出される場合があります。均一な照明下での撮影を推奨します。
サーバースリープ (Render Free)
無料プランのため、15分間アクセスがないとサーバーがスリープします。初回アクセス時は起動に30〜60秒かかります。
履歴の永続化
鑑定履歴はサーバーメモリ上に保存されるため、サーバー再起動時にリセットされます。