diff --git a/CLAUDE.md b/CLAUDE.md index 6242d33..d31024d 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -4,12 +4,12 @@ ## 開発進捗 -現在の進捗: GUIDE_01 に従いプロジェクト立ち上げ中 +現在の進捗: フェーズ 5(規約整備)まで完了.次はフェーズ 6(開発計画) ※ ステップ完了時にここを更新すること. ## 必須ルール(コード実装時) - +- コーディング規約は GUIDE_06,テスト方針は GUIDE_08,エラーハンドリングは GUIDE_09 を参照 ### Git 運用(GUIDE_04 準拠) @@ -45,16 +45,24 @@ - ファイル命名規則: docs/01_GUIDE/GUIDE_03_ファイル命名規則.md - Git 運用ルール: docs/01_GUIDE/GUIDE_04_Git運用ルール.md - エージェント運用ルール: docs/01_GUIDE/GUIDE_05_エージェント運用ルール.md -- ※ コーディング規約,テスト方針等はプロジェクト立ち上げ時に作成する(GUIDE_01 参照) +- コーディング規約: docs/01_GUIDE/GUIDE_06_コーディング規約.md +- ディレクトリ構造規則: docs/01_GUIDE/GUIDE_07_ディレクトリ構造規則.md +- テスト方針: docs/01_GUIDE/GUIDE_08_テスト方針.md +- エラーハンドリング方針: docs/01_GUIDE/GUIDE_09_エラーハンドリング方針.md +- リファクタリング方針: docs/01_GUIDE/GUIDE_10_リファクタリング方針.md +- 機能実装完了フロー: docs/01_GUIDE/GUIDE_11_機能実装完了フロー.md ### 02_ENV(環境) - +- 技術スタック: docs/02_ENV/ENV_01_技術スタック.md +- 環境構築手順: docs/02_ENV/ENV_02_環境構築手順.md +- 管理者用環境構築手順: docs/02_ENV/ENV_03_管理者用環境構築手順.md ### 03_PLAN(計画) - +- 要件定義書: docs/03_PLAN/PLAN_01_要件定義書.md +- 開発ステップ: docs/03_PLAN/PLAN_02_開発ステップ.md ### 04_SPEC(仕様・設計) - +- アーキテクチャ設計: docs/04_SPEC/SPEC_01_アーキテクチャ設計.md diff --git "a/docs/01_GUIDE/GUIDE_06_\343\202\263\343\203\274\343\203\207\343\202\243\343\203\263\343\202\260\350\246\217\347\264\204.md" "b/docs/01_GUIDE/GUIDE_06_\343\202\263\343\203\274\343\203\207\343\202\243\343\203\263\343\202\260\350\246\217\347\264\204.md" new file mode 100644 index 0000000..c649ff5 --- /dev/null +++ "b/docs/01_GUIDE/GUIDE_06_\343\202\263\343\203\274\343\203\207\343\202\243\343\203\263\343\202\260\350\246\217\347\264\204.md" @@ -0,0 +1,63 @@ +# コーディング規約 (Coding Standards) + +基本方針として PEP 8 および Ruff の自動チェックに準拠する.本ガイドでは PEP 8 でカバーされないプロジェクト固有のルールのみ定義する. + +## フォーマット (Formatting) + +- フォーマッター・リンター: Ruff(`ruff.toml` で設定済み) +- 行長: 88 文字(`ruff.toml` で設定済み) +- クォート: ダブルクォート `"` + +## 命名規則 (Naming) + +PEP 8 に準拠する. + +| 対象 | 形式 | 例 | +| --- | --- | --- | +| モジュール | `snake_case` | `uniformity.py` | +| 関数・変数 | `snake_case` | `calc_cov` | +| 定数 | `UPPER_SNAKE_CASE` | `DEFAULT_ROI_SIZE` | +| クラス | `PascalCase` | `UniformityResult` | + +## import 順序 (Import Order) + +Ruff(`isort` 互換)で自動整列する.順序: + +1. 標準ライブラリ +2. サードパーティ(numpy,cv2,colour 等) +3. プロジェクト内モジュール + +## 型ヒント (Type Hints) + +- 関数の引数と戻り値に型ヒントを付ける +- NumPy 配列は `numpy.ndarray` を使用する + +```python +def calc_cov(image: numpy.ndarray) -> float: +``` + +## コメント (Comments) + +- 「何をしているか」ではなく「なぜそうしているか」を書く +- 論文・規格への参照がある場合はコメントに明記する + +```python +# CIE ΔE2000 を使用(CIEDE2000, CIE 142-2001) +delta_e = colour.delta_E(lab1, lab2, method="CIE 2000") +``` + +## docstring + +- 公開関数には Google スタイルの docstring を付ける + +```python +def load_image(path: str) -> numpy.ndarray: + """PNG 画像を読み込み RGB 配列として返す. + + Args: + path: 画像ファイルのパス. + + Returns: + RGB 画像の NumPy 配列(H x W x 3, uint8). + """ +``` diff --git "a/docs/01_GUIDE/GUIDE_07_\343\203\207\343\202\243\343\203\254\343\202\257\343\203\210\343\203\252\346\247\213\351\200\240\350\246\217\345\211\207.md" "b/docs/01_GUIDE/GUIDE_07_\343\203\207\343\202\243\343\203\254\343\202\257\343\203\210\343\203\252\346\247\213\351\200\240\350\246\217\345\211\207.md" new file mode 100644 index 0000000..11953bd --- /dev/null +++ "b/docs/01_GUIDE/GUIDE_07_\343\203\207\343\202\243\343\203\254\343\202\257\343\203\210\343\203\252\346\247\213\351\200\240\350\246\217\345\211\207.md" @@ -0,0 +1,38 @@ +# ディレクトリ構造規則 (Directory Structure) + +## プロジェクトルート (Project Root) + +```text +MiniTias-Evaluation/ +├── src/ # ソースコード +│ ├── io/ # 画像の読み込み +│ ├── analysis/ # 解析ロジック +│ ├── visualization/ # 可視化 +│ └── export/ # 結果出力 +├── scripts/ # 実行スクリプト +├── tests/ # テストコード +├── data/ # 入力画像(Git 管理外) +├── output/ # 解析結果(Git 管理外) +├── docs/ # ドキュメント +└── MiniTias/ # 参照用コピー(Git 管理外) +``` + +## 配置ルール (Placement Rules) + +| 種類 | 配置先 | 備考 | +| --- | --- | --- | +| 解析ロジック | `src/` 配下の該当パッケージ | 1 モジュール = 1 責務 | +| 実行スクリプト | `scripts/` | CLI のエントリーポイント | +| テスト | `tests/` | `src/` の構造に対応させる | +| 入力画像 | `data/{装置名}/{撮影物}/` | 例: `data/minitias/whiteboard/` | +| 出力結果 | `output/figures/`,`output/results/` | 図は PNG,数値は CSV | +| 設定ファイル | プロジェクトルート | `pyproject.toml`,`ruff.toml` 等 | + +## テストの対応関係 (Test Mapping) + +`tests/` は `src/` のディレクトリ構造に対応させる. + +```text +src/analysis/uniformity.py → tests/analysis/test_uniformity.py +src/io/loader.py → tests/io/test_loader.py +``` diff --git "a/docs/01_GUIDE/GUIDE_08_\343\203\206\343\202\271\343\203\210\346\226\271\351\207\235.md" "b/docs/01_GUIDE/GUIDE_08_\343\203\206\343\202\271\343\203\210\346\226\271\351\207\235.md" new file mode 100644 index 0000000..35eb0ad --- /dev/null +++ "b/docs/01_GUIDE/GUIDE_08_\343\203\206\343\202\271\343\203\210\346\226\271\351\207\235.md" @@ -0,0 +1,47 @@ +# テスト方針 (Testing Strategy) + +## テストフレームワーク (Framework) + +- pytest を使用する(`pyproject.toml` で設定済み) + +## テストの種類 (Test Types) + +| 種類 | 対象 | 例 | +| --- | --- | --- | +| ユニットテスト | 個々の関数・モジュール | `calc_cov` が既知の配列で正しい値を返す | +| 統合テスト | パイプライン全体の連結 | 画像読み込みから CSV 出力まで通しで動く | + +## テスト対象の優先度 (Priority) + +1. **解析ロジック**(`uniformity.py`,`color.py`)— 数値の正しさが論文の信頼性に直結する +2. **入出力**(`loader.py`,`exporter.py`)— 形式変換のミスを防ぐ +3. **可視化**(`plotter.py`)— 出力ファイルが生成されることを確認する程度でよい + +## テストデータ (Test Data) + +- 小さなテスト用画像(例: 8x8 px)を `tests/fixtures/` に配置する +- 既知の値を持つ合成画像で期待値と比較する + +```python +# 例: 均一な白画像(全ピクセル 200)→ CoV = 0.0 +uniform_image = numpy.full((8, 8), 200, dtype=numpy.uint8) +assert calc_cov(uniform_image) == 0.0 +``` + +## 実行方法 (Execution) + +```bash +# 全テスト実行 +pytest + +# 特定のテストファイル +pytest tests/analysis/test_uniformity.py + +# 詳細出力 +pytest -v +``` + +## カバレッジ基準 (Coverage) + +- 解析ロジック(`src/analysis/`): 主要関数を網羅する +- 厳密なカバレッジ率は設けない(研究用プロジェクトのため) diff --git "a/docs/01_GUIDE/GUIDE_09_\343\202\250\343\203\251\343\203\274\343\203\217\343\203\263\343\203\211\343\203\252\343\203\263\343\202\260\346\226\271\351\207\235.md" "b/docs/01_GUIDE/GUIDE_09_\343\202\250\343\203\251\343\203\274\343\203\217\343\203\263\343\203\211\343\203\252\343\203\263\343\202\260\346\226\271\351\207\235.md" new file mode 100644 index 0000000..124c58e --- /dev/null +++ "b/docs/01_GUIDE/GUIDE_09_\343\202\250\343\203\251\343\203\274\343\203\217\343\203\263\343\203\211\343\203\252\343\203\263\343\202\260\346\226\271\351\207\235.md" @@ -0,0 +1,38 @@ +# エラーハンドリング方針 (Error Handling) + +## 基本方針 (Principle) + +- 研究用のローカル実行ツールのため,過度な防御的プログラミングは行わない +- エラーは早期に検出し,原因がわかるメッセージで失敗させる + +## エラーの分類 (Error Categories) + +| 分類 | 例 | 対処 | +| --- | --- | --- | +| 入力エラー | 画像ファイルが存在しない,形式が不正 | メッセージを出して即終了 | +| 計算エラー | ゼロ除算,配列サイズ不一致 | 原因を特定できるメッセージで例外を送出 | +| 出力エラー | 書き込み先ディレクトリが存在しない | ディレクトリを自動作成する | + +## 実装ルール (Rules) + +- 入力の検証は **システム境界**(画像読み込み時)で行う + +```python +def load_image(path: str) -> numpy.ndarray: + if not Path(path).exists(): + raise FileNotFoundError(f"画像ファイルが見つかりません: {path}") +``` + +- 内部関数間では型や値の検証を重複させない +- `print` ではなく例外で失敗を通知する +- 例外は握りつぶさない(空の `except:` 禁止) + +## ログ出力 (Logging) + +- 現時点では `print` による簡易出力で十分とする +- 処理の開始・完了を表示する程度にとどめる + +```python +print(f"解析開始: {image_path}") +print(f"結果を保存しました: {output_path}") +``` diff --git "a/docs/01_GUIDE/GUIDE_10_\343\203\252\343\203\225\343\202\241\343\202\257\343\202\277\343\203\252\343\203\263\343\202\260\346\226\271\351\207\235.md" "b/docs/01_GUIDE/GUIDE_10_\343\203\252\343\203\225\343\202\241\343\202\257\343\202\277\343\203\252\343\203\263\343\202\260\346\226\271\351\207\235.md" new file mode 100644 index 0000000..eaa15b3 --- /dev/null +++ "b/docs/01_GUIDE/GUIDE_10_\343\203\252\343\203\225\343\202\241\343\202\257\343\202\277\343\203\252\343\203\263\343\202\260\346\226\271\351\207\235.md" @@ -0,0 +1,27 @@ +# リファクタリング方針 (Refactoring Policy) + +## 判断基準 (When to Refactor) + +以下に該当する場合にリファクタリングを検討する. + +- 同じ処理が 3 箇所以上に重複している +- 1 つの関数が複数の責務を持っている +- 関数の引数が 5 つ以上になっている +- テストが書きにくい構造になっている + +## 実施タイミング (Timing) + +- 機能実装の完了後(`/implement` の Phase 3)に行う +- 機能追加とリファクタリングは同一コミットに混ぜない + +## 方針 (Approach) + +- テストが通っている状態を維持しながら変更する +- 外部から見た振る舞い(入出力)を変えない +- 変更前にテストを実行し,変更後にも同じテストが通ることを確認する + +## やらないこと (Out of Scope) + +- 動いているコードの「見た目だけ」の書き換え(Ruff が自動で対応する範囲) +- 将来の要件を見越した過度な抽象化 +- 使われていないコードの温存(不要なら削除する) diff --git "a/docs/01_GUIDE/GUIDE_11_\346\251\237\350\203\275\345\256\237\350\243\205\345\256\214\344\272\206\343\203\225\343\203\255\343\203\274.md" "b/docs/01_GUIDE/GUIDE_11_\346\251\237\350\203\275\345\256\237\350\243\205\345\256\214\344\272\206\343\203\225\343\203\255\343\203\274.md" new file mode 100644 index 0000000..75b7151 --- /dev/null +++ "b/docs/01_GUIDE/GUIDE_11_\346\251\237\350\203\275\345\256\237\350\243\205\345\256\214\344\272\206\343\203\225\343\203\255\343\203\274.md" @@ -0,0 +1,35 @@ +# 機能実装完了フロー (Implementation Completion Flow) + +## 概要 (Overview) + +機能実装からコミットまでに実施するチェックリスト.`/implement` の全フェーズ完了後に確認する. + +## チェックリスト (Checklist) + +### コード品質 + +- [ ] Ruff でフォーマット・リントを実行しエラーがないこと + +```bash +ruff check src/ tests/ +ruff format --check src/ tests/ +``` + +### テスト + +- [ ] pytest で全テストが通ること + +```bash +pytest +``` + +### ドキュメント + +- [ ] 公開関数に docstring があること +- [ ] API やデータ構造を変更した場合,`docs/` を更新したこと + +### コミット前の最終確認 + +- [ ] `git diff` で意図しない変更が含まれていないこと +- [ ] `.env` やクレデンシャルがステージングされていないこと +- [ ] コミットメッセージが GUIDE_04 の書式に従っていること diff --git "a/docs/03_PLAN/PLAN_02_\351\226\213\347\231\272\343\202\271\343\203\206\343\203\203\343\203\227.md" "b/docs/03_PLAN/PLAN_02_\351\226\213\347\231\272\343\202\271\343\203\206\343\203\203\343\203\227.md" new file mode 100644 index 0000000..c93e2c5 --- /dev/null +++ "b/docs/03_PLAN/PLAN_02_\351\226\213\347\231\272\343\202\271\343\203\206\343\203\203\343\203\227.md" @@ -0,0 +1,49 @@ +# 開発ステップ (Development Steps) + +## 方針 (Approach) + +PLAN_01 の検証対象の優先度に従い,段階的に実装する.各ステップは独立してテスト・実行可能な単位とする. + +## ステップ一覧 (Steps) + +### ステップ 1: プロジェクト骨格の構築 + +- `src/`,`tests/` のディレクトリ・`__init__.py` を作成 +- `loader.py` で PNG 読み込み・ROI 抽出を実装 +- ユニットテストで動作確認 + +### ステップ 2: MiniTIAS 照明均一性評価 + +- `uniformity.py` で輝度分布・均一性指標(CoV,標準偏差,最大/最小比)を実装 +- `plotter.py` で輝度マップ・ヒストグラムを生成 +- `exporter.py` で CSV・PNG 出力 +- MiniTIAS の白板画像で実行し結果を確認 + +### ステップ 3: TIAS との照明均一性比較 + +- ステップ 2 のパイプラインを TIAS 画像にも適用 +- 装置間の比較グラフ(並列表示,差分)を追加 +- 比較結果を CSV に出力 + +### ステップ 4: 色再現性評価 + +- `color.py` で sRGB → L\*a\*b\* 変換・ΔE2000 計算を実装 +- 舌模型画像の色差を装置間で比較 +- 比較グラフ・表を出力 + +### ステップ 5: 実行スクリプトの整備 + +- `run_analysis.py` で全解析を一括実行できるようにする +- コマンドライン引数で解析対象を切り替え可能にする + +## 依存関係 (Dependencies) + +```text +ステップ 1 → ステップ 2 → ステップ 3 + → ステップ 4 + → ステップ 5 +``` + +- ステップ 1 はすべてのステップの前提 +- ステップ 3 と 4 はステップ 2 の完了後,並行して進めることも可能 +- ステップ 5 は 3・4 の完了後 diff --git "a/docs/04_SPEC/SPEC_01_\343\202\242\343\203\274\343\202\255\343\203\206\343\202\257\343\203\201\343\203\243\350\250\255\350\250\210.md" "b/docs/04_SPEC/SPEC_01_\343\202\242\343\203\274\343\202\255\343\203\206\343\202\257\343\203\201\343\203\243\350\250\255\350\250\210.md" new file mode 100644 index 0000000..ab37fa7 --- /dev/null +++ "b/docs/04_SPEC/SPEC_01_\343\202\242\343\203\274\343\202\255\343\203\206\343\202\257\343\203\201\343\203\243\350\250\255\350\250\210.md" @@ -0,0 +1,59 @@ +# アーキテクチャ設計 (Architecture) + +## ディレクトリ構造 (Directory Structure) + +```text +MiniTias-Evaluation/ +├── src/ +│ ├── io/ +│ │ └── loader.py # 画像読み込み(OpenCV) +│ ├── analysis/ +│ │ ├── uniformity.py # 照明均一性評価 +│ │ └── color.py # 色再現性評価(ΔE,L*a*b*) +│ ├── visualization/ +│ │ └── plotter.py # グラフ・図の生成(Matplotlib) +│ └── export/ +│ └── exporter.py # CSV・画像の出力(pandas) +├── scripts/ +│ └── run_analysis.py # 実行エントリーポイント +├── tests/ +├── data/ +│ ├── minitias/whiteboard/ +│ └── tias/whiteboard/ +└── output/ +``` + +## 処理パイプライン (Processing Pipeline) + +```text +PNG 画像 + ↓ loader.py 画像読み込み(OpenCV,BGR→RGB) + ↓ loader.py ROI 抽出(解析対象領域の切り出し) + ↓ uniformity.py 輝度分布の計算(均一性指標: CoV 等) + color.py 色空間変換(sRGB → L*a*b*)・ΔE 計算 + ↓ plotter.py グラフ生成(輝度マップ,色差分布等) + ↓ exporter.py CSV・PNG 出力 +``` + +## モジュール設計 (Module Design) + +| モジュール | 責務 | 主な依存 | +| --- | --- | --- | +| `loader.py` | PNG 読み込み・ROI 抽出 | OpenCV,NumPy | +| `uniformity.py` | 輝度分布・均一性指標(CoV,標準偏差等)の算出 | NumPy | +| `color.py` | sRGB→L\*a\*b\* 変換・ΔE2000 計算 | colour-science,scipy | +| `plotter.py` | 輝度マップ・棒グラフ・散布図の生成 | Matplotlib | +| `exporter.py` | 数値結果を CSV,図を PNG で保存 | pandas,Matplotlib | +| `run_analysis.py` | 各モジュールを呼び出す実行スクリプト | 全モジュール | + +## 入出力仕様 (I/O Specification) + +### 入力 (Input) + +- 形式: PNG(8bit RGB) +- 配置: `data/minitias/whiteboard/`,`data/tias/whiteboard/` + +### 出力 (Output) + +- `output/figures/` — グラフ画像(PNG,論文掲載用) +- `output/results/` — 数値結果(CSV)