diff --git a/.claude/rules/coding-style.md b/.claude/rules/coding-style.md new file mode 100644 index 0000000..6888f01 --- /dev/null +++ b/.claude/rules/coding-style.md @@ -0,0 +1,48 @@ +--- +paths: ["Tongue extraction/**/*.cs", "DeepTIAS.Tests/**/*.cs"] +--- + +# コーディング規約 (Coding Style) + +C# のコードを書くときは本規約に従うこと.基本は Microsoft の [C# のコーディング規則](https://learn.microsoft.com/ja-jp/dotnet/csharp/fundamentals/coding-style/coding-conventions) と [識別子の名前付け規則](https://learn.microsoft.com/ja-jp/dotnet/csharp/fundamentals/coding-style/identifier-names) に従い,本規約ではプロジェクト固有の点だけを定める. + +## 既存コードの扱い (Legacy Code) + +- 引き継いだコードは命名が混在している(`path_outputDir`・`mat_input` のようなスネークケースのローカル変数,`Button_start_Click` のようなハンドラ名). +- **新しく書くコードは本規約に従う.**既存コードの名前を変えるのは,その箇所を整理・修正するときに限る.名前を変えるためだけの一括変更はしない(差分が大きくなり,挙動を変えていないことの確認が難しくなるため). +- WinForms デザイナが生成する名前(`button_start`・`Form1_Load` 等)は,デザイナとの対応が崩れるため変えない. + +## 命名 (Naming) + +| 対象 | 形式 | 例 | +| --- | --- | --- | +| クラス・メソッド・プロパティ・定数 | PascalCase | `TongueDetector`,`DetectTongue`,`ScoreThreshold` | +| ローカル変数・引数 | camelCase | `outputDir`,`inputImage` | +| private フィールド | `_` + camelCase | `_session` | +| インターフェース | `I` + PascalCase | `IFeatureExtractor` | + +- 画像処理の変数は,型が分かる名前にする(`Mat` なら `mask`・`binaryImage`,パスなら `maskPath` のように `Path`・`Dir` を付ける). +- 論文や手法の名前(`Chiu`・`FiveClick` 等)は既存の呼び方をそのまま使う. + +## 書式 (Formatting) + +- インデントはスペース 4 つ.波かっこは次の行に置く(Visual Studio の既定). +- `var` は右辺から型が明らかなときだけ使う. +- `using` は `System` 系を先頭にし,未使用のものは残さない. + +## マジックナンバー (Magic Numbers) + +- 解析結果に影響する数値(検出スコアのしきい値 0.5,小領域除去の面積 500,領域分割の比率 0.2 等)は,名前の付いた定数にまとめる.値は変えない([解析処理仕様](../../docs/04_SPEC/SPEC_02_解析処理仕様.md) が基準). +- 定数には,何を表し,単位は何か(画素・比率等)をコメントで書く. + +## 外部の実行ファイル・DLL の呼び出し (External Binaries) + +- 外部 exe(`TongueFeatures.exe`・`TongueAnalysis.exe`)を呼ぶ処理は 1 か所にまとめ,引数の並びと出力ファイルをコメントに書く. +- ネイティブ DLL の `DllImport` 宣言は専用のクラスにまとめる. + +## コメント (Comments) + +- コメントは日本語で書く. +- 「何をしているか」ではなく「なぜそうしているか」を書く(手法の根拠となる論文,値を決めた理由等). +- public なクラス・メソッドには `///` の XML ドキュメントコメントで,役割・引数・戻り値を書く. +- 使わなくなったコードはコメントアウトで残さず削除する(履歴は git に残る). diff --git a/.claude/rules/error-handling.md b/.claude/rules/error-handling.md new file mode 100644 index 0000000..7a02b90 --- /dev/null +++ b/.claude/rules/error-handling.md @@ -0,0 +1,29 @@ +--- +paths: ["Tongue extraction/**/*.cs"] +--- + +# エラー処理方針 (Error Handling) + +例外処理・ログ出力を書くときは本方針に従うこと. + +## エラーの分類と扱い (Error Categories) + +| 分類 | 例 | 扱い | +| --- | --- | --- | +| 画像 1 枚だけの失敗 | 舌を検出できない,舌領域が 1 つにまとまらない | その画像を失敗として記録し,次の画像へ進む.`analysis.csv` の失敗行の形式(`<画像名>,Tongue detection error` 等)は変えない | +| 解析を続けられない失敗 | モデル・外部 exe・DLL が見つからない,入力フォルダが無い | 解析を止め,原因(どのファイルが無いか)をダイアログで伝える | +| 想定外の例外 | 上記以外 | 解析を止め,ダイアログで伝え,ログに詳細を残す.画面を操作できる状態に戻す | + +## 決まり (Rules) + +- **例外を握りつぶさない.**`catch` だけで何もしない,または `catch { }` で原因を捨てる書き方をしない.捕まえた例外はログに残す. +- 捕まえる例外の型をできるだけ具体的にする(`catch (Exception)` は最上位の処理だけにする). +- `BackgroundWorker` で解析するときは `RunWorkerCompleted` で `e.Error` を確認し,例外を画面に伝える. +- 外部 exe を呼んだら終了コードと出力ファイルの有無を確認し,失敗なら「画像 1 枚だけの失敗」として扱う. +- ダイアログ(`MessageBox`)は画面のスレッドから出す(解析スレッドからは `Invoke` を使う). + +## ログ (Logging) + +- 解析のログは出力フォルダに `log.txt` として書き出す(画像ごとの開始・終了・失敗理由,想定外の例外の詳細). +- `Console.WriteLine` は WinForms アプリでは見えないため,確認用の出力に使わない. +- デバッグ用の表示(`Cv2.ImShow`・`Cv2.WaitKey`・出力先の固定等)をコミットに残さない. diff --git a/.claude/rules/project-structure.md b/.claude/rules/project-structure.md new file mode 100644 index 0000000..724a66c --- /dev/null +++ b/.claude/rules/project-structure.md @@ -0,0 +1,44 @@ +--- +paths: ["Tongue extraction/**", "DeepTIAS.Tests/**", "Tongue extraction.sln"] +--- + +# プロジェクト構成 (Project Structure) + +ファイルを追加・移動するときは本規約に従うこと. + +## ディレクトリ構成 (Directory Layout) + +```text +DeepTIAS/ +├── Tongue extraction.sln # ソリューション +├── Tongue extraction/ # アプリ本体(DeepTIAS2.7.csproj) +│ ├── Form1.cs # 画面と解析の流れ +│ ├── ColorExtractor_fiveClick.cs # 領域分割(Chiu 法・拡張 Chiu 法・5 点法) +│ ├── Program.cs # エントリポイント +│ ├── Properties/ # アセンブリ情報・リソース・設定 +│ └── models/ # 学習済みモデル(Git LFS) +├── DeepTIAS.Tests/ # テストプロジェクト(MSTest.作成予定) +├── ColorSubdivision/ # 試作プロジェクト(ソリューション外.保守対象外) +└── docs/ # ドキュメント +``` + +- フォルダ名 `Tongue extraction`(スペース入り)とプロジェクト名 `DeepTIAS2.7` は,参照の張り替えが多いため当面変えない. + +## 追加するコードの置き場所 (Where New Code Goes) + +`Form1.cs` に解析処理が集中しているため,整理で切り出すコードは以下のフォルダに置く.フォルダは実際にファイルを置くときに作る. + +| フォルダ | 置くもの | 例 | +| --- | --- | --- | +| `Tongue extraction/Analysis/` | 解析の各工程(画面に依存しない処理) | 舌検出,舌領域抽出,形状特徴 | +| `Tongue extraction/External/` | 外部 exe・ネイティブ DLL の呼び出し | `TongueFeatures.exe` の起動,`DllImport` 宣言 | +| `Tongue extraction/IO/` | 入出力フォルダ・CSV の読み書き | 出力フォルダの作成,`analysis.csv` の追記 | + +- **画面(`Form1`)には,画面の更新と操作の受け付けだけを残す.**解析処理は画面の部品(`PictureBox` 等)に触れないようにし,テストから呼べる形にする. +- 1 ファイル 1 クラスを基本とする.ファイル名はクラス名と同じにする. +- 旧形式の csproj はファイルを自動で取り込まないため,追加したファイルは csproj の `` にも登録する(Visual Studio から追加すれば自動で登録される). + +## 実行時に必要なファイル (Runtime Files) + +- モデル・外部バイナリ・雛形フォルダなど,実行時に exe と同じ場所に必要なファイルは,csproj で「出力ディレクトリにコピー」(`CopyToOutputDirectory`)を指定し,ビルドだけで揃うようにする. +- 大きなバイナリ(モデル・exe・DLL)は Git LFS で管理する.新しい拡張子を追加するときは先に `git lfs track` で対象にする. diff --git a/.claude/rules/testing.md b/.claude/rules/testing.md new file mode 100644 index 0000000..75cd5e4 --- /dev/null +++ b/.claude/rules/testing.md @@ -0,0 +1,35 @@ +--- +paths: ["DeepTIAS.Tests/**", "Tongue extraction/**/*.cs"] +--- + +# テスト方針 (Testing) + +テストを書く・実行するときは本方針に従うこと.フレームワークは MSTest を使う([技術スタック](../../docs/02_ENV/ENV_01_技術スタック.md)). + +## テストの種類 (Test Types) + +| 種類 | 目的 | 対象 | +| --- | --- | --- | +| 回帰テスト | コード整理の前後で解析結果が変わらないことを確かめる | サンプル画像を解析した `analysis.csv` と,旧ビルドで出した正解の比較 | +| 単体テスト | 切り出した処理が単体で正しく動くことを確かめる | 領域分割,形状特徴,CSV の組み立て等,画面に依存しない処理 | + +- **回帰テストを最優先する.**本プロジェクトの目的は「解析結果を変えずに整理する」ことであり,その保証の中心になる. +- 画面(`Form1`)の操作は自動テストの対象にしない.人が動作確認する. + +## 回帰テストの決まり (Regression Tests) + +- 正解データ(入力画像と,旧ビルドで出した `analysis.csv`・中間画像)は `DeepTIAS.Tests/TestData/` に置き,Git LFS で管理する. +- 比較は `analysis.csv` の列構成(見出し行)と値で行う.小数の値は,浮動小数点の誤差を考えて許容誤差を決めて比べる(許容誤差は正解データ作成時に決め,テストコードに理由を書く). +- 正解データを作り直すのは,解析結果を変える変更をユーザーが承認したときだけとする.テストを通すために正解データを書き換えてはならない. +- 外部 exe・モデルを使うため時間がかかる.テスト名やカテゴリで単体テストと区別し,単体テストだけを素早く回せるようにする. + +## 単体テストの決まり (Unit Tests) + +- テストメソッド名は `対象_条件_期待結果` の形にする(例: `Get3areaMask_EmptyMask_ReturnsEmpty`). +- 画像を使うテストは,小さな画像をテストコード内で作るか,`TestData/` の画像を使う.PC ごとの絶対パスを書かない. +- 1 つのテストでは 1 つのことだけを確かめる. + +## 実行タイミング (When to Run) + +- コードを変更したら,コミット前に単体テストと回帰テストの両方を実行し,すべて通ることを確認する. +- 実行コマンドは [開発コマンド](../../docs/02_ENV/ENV_04_開発コマンド.md) に記載する.