Files
yoshikazuandClaude Opus 4.8 e4eca6b303 Initial commit: ノーコード画像検査アプリ (MVP + 追加機能一式)
検査レシピ=処理/検査ステップの縦リスト(配線なし)。yfoxlib(yfoximg/yfoxbase)使用。

- ビジュアル・パイプライン(カード+適用後サムネイル+緑/赤 合否)
- テンプレート/対話式ウィザードでレシピ生成(CTaskDialog)
- パラメータのスライダー・ライブ調整
- レシピ保存/読込(*.itr) + 最近使ったファイル(MRU)
- 検査範囲(ROI)を複数マウス指定(ドラッグ追加/右クリック削除)
- カードのドラッグ並べ替え
- 判定結果画像の保存 + 検査ログCSV(項目拡張)
- 処理6種+検査3種(明るさ/白画素率/塊の数)
- /selftest(実行+レシピ往復+結果画像+複数ROI塊カウント検証)、/demo

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-23 09:26:10 +09:00

108 lines
9.5 KiB
Markdown

# CLAUDE.md
This file provides guidance to Claude Code when working with code in this repository.
## 概要
**ImgTestSystem** は yfoxlib(`yfoximg` / `yfoxbase`)を使う **ノーコード画像検査アプリ**(純MFC)。
パラダイムは隣の `C:\debug\ImgChkSystem`(ブロックをワイヤで繋ぐノードエディタ)とは **意図的に別物**:
> **検査レシピ = 上から下へ順に実行する「ステップ」の縦リスト**(配線なし)。
> 料理のレシピ / 検査チェックリストのメタファ。ステップは2種:
> - **処理**(画像を加工): グレー化 / メディアン / 二値化(帯) / 大津 / ガンマ / コントラスト
> - **検査**(測って範囲判定→PASS/FAIL): 平均輝度 / 白画素率
UI: 左=ステップ縦リスト(追加/削除/↑↓)・右上=選択ステップのパラメータ入力・右下=作業画像プレビュー・
上部=[画像を開く]/[実行]と総合判定バナー。ノーコード=ドロップダウンと数値入力のみ、コードもワイヤも書かない。
## ビルド
VS2022 (v143 / MFC Dynamic / Release|x64 / /utf-8 / stdcpp17)。
```powershell
$msb="C:\Program Files\Microsoft Visual Studio\2022\Professional\MSBuild\Current\Bin\amd64\MSBuild.exe"
& $msb ImgTestSystem.sln /p:Configuration=Release /p:Platform=x64
```
- リンク: `yfoximg.lib;yfoxbase.lib;gdiplus.lib`(libdir `C:\debug\yfoxlib\x64\$(Configuration)`)。
- include: `C:\debug\yfoxlib\yfoximg;...\yfoxbase;...\yfoxbase\include`。
- PostBuild で `yfoximg.dll`/`yfoxbase.dll` を出力先へコピー。出力=`bin\x64\<Config>\`。
## アーキテクチャ
UI非依存の **core/** と MFC UI層(ルート)に分離。
### core/(ウィンドウ非依存)
- `Recipe.h` — `StepKind`(処理/検査)、`StepParam`(数値パラメータ)、`Step`、`Recipe`(ステップの並び)。
- `StepCatalog.h` — 種別→表示名 `StepName` / 検査判定 `IsInspect` / 既定パラメータ生成 `MakeStep` / パレット `AllStepKinds`。
**新ステップ追加は `StepKind` に足し、この2関数(`StepName`/`MakeStep`)と `InspectEngine` の `RunStep` に1ケース足すだけ。**
- `InspectEngine.h/.cpp` — **唯一 yfoximg に依存する層**。`LoadImage`→`Run(recipe, upTo)` で作業画像を原画像から作り直し、
各ステップを `CImgProcessing`(`RGB2BW`/`Threshold`/`Threshold_Otsu`/`Avg`/`Gamma`/`Contrast`/`Median`)で適用。
`upTo>=0` でその番号までプレビュー実行、`-1` で全実行し総合 PASS/FAIL を返す。`DrawWork` でプレビュー描画。
### UI層(ルート)
- `App.h/.cpp` — `CImgTestApp:CWinApp`。GDI+ 起動、`/selftest` 分岐、`CMainFrame` 生成。
- `MainFrame.h/.cpp` — `CMainFrame:CFrameWnd`。子コントロールは **リソース不使用で OnCreate で動的生成**(.rc なし=RC の cp932 罠を回避)。
リスト選択→パラメータ欄ロード+`PreviewUpTo`、[追加/削除/↑↓]でレシピ編集、[実行]で全実行+バナー更新。
- `SelfTest.cpp` — `/selftest`(ヘッドレス)。合成画像→レシピ実行→`selftest_result.txt`(UTF-8)。
## yfoximg 作法(重要)
- アンブレラ `yfoximg.h`(OpenGL 引き込み)は使わず **`ImgProcessing.h` を直接 include**。
- yfoximg は **NOMINMAX を定義しない**(裸の `min`/`max` マクロ前提)。GDI+ も min/max マクロを要求するため、
`ImgProcessing.h` を含む TU(`InspectEngine.cpp`/`SelfTest.cpp`)では **`std::min/std::max` を使わない**(手書きクランプ)。
- 8bit グレー画像は `SetGrayPalette()` してから `Draw`/`Save`。処理系は R1(入力不変)・R2(出力は新規 `CDiBitmap`)。
- 画像は 8/24/32bit を受理。`Ensure8` が 32→24(手動)→`RGB2BW` で 8bit へ正規化してから濃淡系処理を行う。
## 検証
- `ImgTestSystem.exe /selftest` → 合成画像(一様輝度128)で グレー化→平均輝度→白画素率 を実行し PASS を確認、
`selftest_result.txt` を出力(終了コード 0=PASS)。
## わかりやすさ強化(3方式を統合)
- **ビジュアル・パイプライン**(`PipelineView.*`, `CPipelineView:CWnd`): 各ステップをカード化し、
「そのステップ適用後のサムネイル」を縦に並べる=画像が上から下へ変化する様子が見える。
検査カードは大きな緑✓/赤✗バッジ+測定値。左ストライプ 青=処理/橙=検査。ダブルバッファ描画・ホイール/スクロール対応。
**罠**: `CDiBitmap::Draw`(サムネ)は DC の `BkMode` を OPAQUE/暗色へ戻すので、直後の文字描画前に
`SetBkMode(TRANSPARENT)` を必ず再設定する(でないと暗地に明字で反転)。
- **テンプレート**(`core/Templates.h` + `wizard::ChooseTemplate`): 目的(キズ/欠け/明るさ/文字)を選ぶと完成レシピが入る。
- **対話式ウィザード**(`Wizard.*` + `CTaskDialog`): Q&A でレシピ生成。.rc 不要のため `CTaskDialog`(要 Common-Controls v6 マニフェスト=stdafx.h の pragma)。
- 右パネル: 選択ステップのパラメータを **CSliderCtrl でライブ調整**(`OnHScroll`→即再実行→サムネ更新)。整数域は実値、
ガンマ等の実数域は 0..1000 マッピング。合否バナーは `OnCtlColor` で緑/赤/灰に色分け。
- 検査種別に **塊(キズ/穴)の数**(`InspectBlobCount`)を追加(`LabelingInit`/`Labeling`/`m_nLabelCount`)。
## 検証(追加)
- `ImgTestSystem.exe /demo` → デモ画像(明るい地に暗い欠陥3点)+ キズ検査テンプレを読み込み実行(画面確認用)。
スクリーンショットは `PrintWindow(PW_RENDERFULLCONTENT=2)` で捕捉可(Windows PowerShell 5.1 + System.Drawing)。
## レシピ保存/ROI/並べ替え/検査ログ(追加実装)
- **レシピ保存/読込**(`core/RecipeStore.*`): 人が読める UTF-8 テキスト `*.itr`(`STEP <id>` / `PARAM <key> <val>` / `ROI ...`)。
`StepKindId`/`StepKindFromId`(`StepCatalog.h`)で enum を安定文字列 ID として永続化。読込は `MakeStep` 既定へキー一致で上書き(前方互換)。メニュー ファイル。
- **検査範囲 ROI**(`Recipe::roiEnabled/roi`): 大プレビュー上をドラッグして矩形指定(`CMainFrame::OnLButtonDown/MouseMove/Up`)。
描画メソッド `DrawShot/DrawSource` は**実際に描いた矩形**(アスペクト維持=`AspectFit`)を返し、client↔画像座標の相互変換に使う。
検査は ROI 内で計測: 明るさ=`RectAvg(roi)` / 白画素率=`Threshold(...,roi)`÷ROI面積 / 塊数=`Labeling(...,roi)`。処理ステップは寸法不変なので全ステップ ROI 同座標系。ROI は大プレビュー+カードサムネに黄枠表示。メニュー 検査範囲。
- **カードのドラッグ並べ替え**(`CPipelineView`): 押下→しきい値超で `m_dragging`、青い挿入インジケータ、離すと `WM_PV_MOVESTEP(from,slot)`→`CMainFrame::OnPipeMoveStep` が並べ替え+再実行。
- **判定結果画像の保存 / 検査ログ**: `InspectEngine::SaveResultImage`=最終画像を24bit化し ROI枠+PASS/FAIL バナー+検査要約(縁取り文字)を焼き込み保存(拡張子で png/bmp/jpg)。
検査ログ=記録フォルダ(`SHBrowseForFolder`)へ `result_<ts>.png` 保存+`inspect_log.csv`(UTF-8 BOM, 日時/総合/画像/詳細)追記、フォルダを開く。メニュー 検査ログ。
- **⚠ 罠**: Windows ヘッダの `#define small char`(rpcndr.h)のため、ローカル変数名に `small` を使うと C2628。`fSmall` 等にする。
## 複数ROI / MRU / CSV拡張(追加実装)
- **複数ROI**(`Recipe::rois` = `vector<CRect>`。空=画像全体): 大プレビューを**ドラッグで範囲追加**、**右クリックでその範囲を削除**、
メニュー 検査範囲=「最後を取り消す」「すべてリセット」。検査は全ROIを合算(明るさ=面積重み付き平均 / 白画素率=合算/合計面積 / 塊数=全ROIマスクを結合→union bbox でラベリング)。
大プレビュー+カード+結果画像に黄枠+番号を描画。`.itr` は `ROI l t r b` を範囲ごとに1行(旧 `ROI enabled l t r b` 5値も読める)。
- **⚠ 重要バグ修正**: yfoximg `CImgProcessing::Threshold` を**同一バッファへ sub-rect で複数回呼ぶとマスクが壊れる**(2個ROIで塊数0になった)。
`MakeBinary` は Threshold をやめ、**画素を直接走査してROI内だけ白く塗る**方式に変更(8bit前提=Ensure8済)。`/selftest` に複数ROI塊カウント検証(全体3/大ROI2/小2個ROI2)を常設。
- **最近使ったレシピ(MRU)**: 最大5件を `HKCU\Software\YFox\ImgTestSystem\Recent\File1..5` に保存(`SetRegistryKey(L"YFox")`)。
ファイルメニューの「最近使ったレシピ」サブメニュー(`m_hRecentMenu` を保持し `UpdateRecentMenu` で再構築、`ON_COMMAND_RANGE`)。開く/保存時に `AddRecent`。存在しない項目はクリック時に一覧から除去提案。
- **検査ログCSV 拡張**: 列= 日時,総合判定,元画像,レシピ,ステップ数,検査数,合格数,不合格数,検査範囲数,結果画像,詳細(UTF-8 BOM)。記録フォルダも `HKCU\...\Log\Folder` に永続化。
## 現状
処理6種+検査3種、ビジュアル・パイプライン、テンプレート、ウィザード、スライダー調整、
レシピ保存/読込(+MRU)、複数ROI 指定、カードのドラッグ並べ替え、判定結果画像保存/検査ログ(CSV拡張)、/selftest・/demo。
`/selftest` は 実行 + レシピ往復一致 + 結果画像保存 + 複数ROI塊カウント を検証(RESULT: PASS)。