이 저장소에서 작업하는 Claude Code(또는 다른 AI 에이전트)와 신규 참여자를 위한 지침이다. 작업을 시작하기 전에 이 문서를 끝까지 읽어라.
MVTec HALCON 13 의 Regions ▸ Features 오퍼레이터 40종을, HALCON SDK 없이 C++ 자체 엔진으로 재현하는 라이브러리다.
- 최종 사용처: 2차전지 코터 / 슬리터 / 롤프레스 머신비전 검사 프로그램 (MFC, 멀티바이트)
- 이 라이브러리를 static lib 로 링크해 불량 Blob 의 형상 특징값을 뽑는다
- HALCON 런타임 라이선스 없이 동일한 수치를 얻는 것이 존재 이유다
값이 틀린 40종보다, 값이 맞는 5종이 낫다.
오퍼레이터를 많이 구현했다는 것은 성과가 아니다. HALCON 실측값과 일치하는 것만 성과다. "일단 다 만들고 나중에 맞추자" 는 금지다.
docs/02_DEFINITIONS.md 에 정의를 쓴다
↓
docs/03_VERIFICATION.md 의 기준 도형으로 기댓값을 손계산한다
↓
(가능하면) HALCON 실측과 대조한다
↓
그 다음에야 코드를 짠다
정의서에 없는 오퍼레이터를 먼저 구현하지 마라. 정의가 틀리면 코드는 전부 폐기다.
- 근거는
docs/reference/halcon13/에 수집된 HALCON 13 원문이다 - 일반적인 컴퓨터비전 통념(Hu 모멘트, OpenCV 관례)으로 대체하지 마라.
원문이 통념과 다른 지점이 최소 14곳 확인됐다 (
docs/00_OVERVIEW.md§5) - 원문에 없으면 "문서에 명시 없음" 으로 남기고 미결 쟁점으로 등록한다. 추측해서 채우면 검증이 불가능해진다
MVTec 문서의 수식은 텍스트가 아니라 MetaPost 인라인 SVG 글리프다. 일반적인 페이지 요약/크롤링으로는 수식이 통째로 누락되거나 분자·분모가 뒤집힌다.
docs/reference/halcon13/ 의 내용은 HTML 글리프 ID(cmmi10/cmr10/cmsy10/cmex10)를
TeX 폰트 인코딩으로 역매핑하고 SVG transform 좌표로 분수선·첨자를 재구성해 복원한 것이다.
이미 복원된 이 아카이브를 신뢰하고 쓰라. 다시 긁으면 품질이 떨어진다.
docs/00_OVERVIEW.md §5 에 14건 전체가 있다. 그중 즉시 사고를 내는 것들:
| # | 함정 | 잘못 짜면 |
|---|---|---|
| 1 | circularity 는 min(1, …), compactness 는 max(1, …) — 클리핑 방향이 반대 |
둘 다 min 으로 짜면 compactness 가 전부 1.0 |
| 2 | convexity = 원본면적 / hull면적 (분자가 원본) |
뒤집으면 항상 ≥ 1, Assertion 위반 |
| 3 | contlength 는 구멍 윤곽을 포함하지 않는다 |
RETR_EXTERNAL 안 쓰면 링에서 1.5배 커진다 |
| 4 | moments_region_2nd 는 정규화가 없다(순수 합) |
면적으로 나누면 전 모멘트 계열이 오염 |
| 5 | 모멘트 부호 규약: 2nd 는 (중심−픽셀), 3rd 는 (픽셀−중심) |
3차 홀수항 부호가 뒤집힌다 |
| 6 | smallest_rectangle2 의 Length1/2 는 반변(half length) |
OpenCV minAreaRect 와 2배 차이 |
| 7 | 픽셀은 면적 1의 사각형이 아니라 무한소 점으로 취급된다 | 1픽셀 두께 리전에서 Rb=0 → 0 나눗셈 크래시 / 단일 픽셀 Diameter 가 √2 로 나온다 |
| 7b | 전경과 배경의 연결성은 반대여야 한다 (전경 8 ↔ 배경 4) | 둘 다 8 로 잡으면 NumHoles·EulerNumber 가 대각 도형에서 모순된 값을 낸다 |
| 8 | region_features 의 feature 이름은 63종, 오퍼레이터 40종과 별개 체계 |
이름 매핑을 오퍼레이터 기준으로 짜면 어긋난다 |
| 항목 | 규칙 | 예 |
|---|---|---|
| 클래스명 | PascalCase | FeatureContext |
| 함수명 | PascalCase | ComputeConvexHull |
| 변수명 | camelCase | itemCount |
| 멤버변수 | m_ 접두사 |
m_runs |
| 들여쓰기 | 탭 | |
| 표준 | C++14 (C++17 은 사용처 툴셋 확인 후) |
- 소스 파일 인코딩은 UTF-8 BOM 필수. BOM 없는 UTF-8 한글 주석은 VS 가 CP949 로 오독해 다음 줄을 삼킨다. 컴파일은 성공하는데 코드가 사라지는 형태라 추적이 극히 어렵다.
- 공개 헤더에 OpenCV 타입(
cv::Mat등)을 노출하지 마라. 사용처마다 OpenCV 버전이 달라 링크가 깨진다. PIMPL 로 숨긴다. - 예외를 공개 API 밖으로 던지지 마라. 내부에서
try-catch로 잡고 HALCON 의 빈 리전 규약(0반환)으로 축약한다. - 0 나눗셈·빈 리전·빈 컨투어는 전부 가드한다. 원문이 명시한 예외 동작을 그대로 재현한다.
- 빌드는 수행하지 않는다. 저장소 소유자가 Visual Studio 에서 직접 빌드한다. (CMake 설정 파일 작성은 해도 되지만, 빌드 명령을 실행하지 마라)
HALCON (row, col) = (y, x) ← 공개 API 는 이걸 따른다
OpenCV cv::Point(x, y) ← 내부 전용, 경계에서 변환
혼동이 값 오류의 최대 원인이다. 변환 지점을 주석으로 명시하라.
docs/reference/halcon13/에서 해당 오퍼레이터의 원문을 찾는다docs/02_DEFINITIONS.md에 절을 추가한다 — 시그니처 / 원문 인용 / 수식 / 구현 지침 / 미결 쟁점docs/03_VERIFICATION.md에 기준 도형 S1~S7 에 대한 기댓값을 손계산해 넣는다- 계산 과정을 같이 적는다. 결과만 적으면 검증이 안 된다
- 두 해석이 갈리면 판별력이 가장 큰 도형을 지정한다
- 그 다음에 구현한다
- 단위테스트가 3번의 기댓값과 일치하는지 확인한다
docs/00_OVERVIEW.md§6 의 현황표 체크박스를 갱신한다
- 1기능 1커밋
- 컨벤셔널 커밋:
feat:fix:docs:test:refactor:chore: - 커밋 메시지는 한국어로 써도 된다
- 예:
feat: circularity 구현 (S1~S7 기댓값 검증 통과)
임의로 결정하지 마라. 다음 순서로 처리한다.
docs/02_DEFINITIONS.md의 해당 오퍼레이터에 미결 쟁점으로 등록 (ID 부여:CV-1형식)docs/03_VERIFICATION.md에 어떤 도형으로 판정할 수 있는지 시험을 설계- 잠정 결론을 근거와 함께 적되, 코드에 두 해석을 스위치로 남긴다
- 저장소 소유자에게 보고한다
| 항목 | 상태 |
|---|---|
| 원문 수집 | ✅ 완료 — 40종 전부, docs/reference/halcon13/ 2094줄 |
| 아키텍처 설계 | ✅ 완료 — docs/01_ARCHITECTURE.md |
| 정의서 | 🟡 14종 / 40종 확정 (1차 5종 + 2차 모멘트 5종 + 3차 구멍 4종) |
| 검증 기댓값 | ✅ 14종 손계산 완료 — 판정 P-1~P-13 해소, 미결 6건 |
| 구현 (1차 배치) | ✅ area_center contlength circularity compactness convexity |
| 배치·검사기 API | ✅ RegionFeatures / ComputeFeatures / ComputeLargestBlobFeatures / SelectLargestBlob |
| 구현 (2차 배치) | ✅ moments_region_2nd moments_region_2nd_invar elliptic_axis eccentricity orientation_region + RegionMoments / ComputeMoments / ComputeFeaturesAndMoments |
| 구현 (3차 배치) | ✅ area_holes connect_and_holes euler_number diameter_region + RegionTopology / ComputeTopology / ComputeFeaturesMomentsAndTopology |
| 단위테스트 | 🟡 1차 PASS 70 / FAIL 0 실측 완료. 2·3차 분은 미실행(빌드 금지 지시) |
| HALCON 실물 대조 (V2) | ⬜ 미실시 — HALCON 13 환경 확보 시 수행 |
기준선: 1차 배치까지 MSVC 19.50 (VS 2026 v14.50) x64 Release, /W4 경고 0, ctest 3/3 실측.
2·3차 배치는 작업트리에만 있고 빌드·실행 검증을 하지 않았다. 소유자가 직접 빌드한다.
⚠️ 이 표는 갱신일 기준이다. 작업 재개 시git log --oneline으로 실제 진도를 먼저 확인하라. 40종 개별 현황은docs/00_OVERVIEW.md§7 이 정본이다.
| ID | 내용 | 해소 방법 |
|---|---|---|
R-1 |
contlength 체인 닫힘 1스텝 차이 (396 vs 395) |
HALCON 실측 1회. compactness 도 함께 영향받는다 |
MI-1 |
moments_region_2nd_invar 의 원점이 무게중심인가 |
S5 실측. 스위치 GLIM_HALCON_INVAR_ORIGIN_BBOX |
EA-2 |
elliptic_axis 의 Phi = −π/2 를 +π/2 로 접는가 |
S4T 실측. 스위치 GLIM_HALCON_PHI_FOLD_HALF_PI |
EC-1 |
Rb=0 일 때 StructureFactor 가 −1 인가 0 인가 |
S4/S6 실측. 스위치 GLIM_HALCON_STRUCTURE_FACTOR_ZERO_ON_RB0 |
OR-2 |
orientation_region 의 +π 후 범위 접기 |
스위치 GLIM_HALCON_ORIENTATION_WRAP |
OR-3 |
대칭 도형의 최원점 동률 | 판정 불가(원문 미명시). 대칭 도형은 집합 소속만 검사 |
HC-1 |
배경 연결성이 4-연결인가 8-연결인가 (전경은 8-연결 고정) | S10 대각 다이아몬드 실측. 스위치 GLIM_HALCON_BACKGROUND_CONNECTIVITY_8. ⚠ 뒤집히면 area_holes·connect_and_holes·euler_number 3종이 동시에 바뀐다 |
HC-3 |
구멍 면적을 리전 전체로 세는가, 성분별 합인가 | S12 실측(40 vs 49). 스위치 없음 — 대안이 중첩 구조에서 정의 불능 |
DR-2 |
최대거리 쌍의 동률 | 판정 불가(원문 미명시). 사전순 최소 쌍으로 고정, Diameter 값만 정확값 대조 |
스위치는 src/Core/Moments.h (2차) 와 src/Core/Holes.h (3차) 상단에 있다.
둘 다 내부 헤더라 사용처를 오염시키지 않는다.
- 2·3차 배치 빌드·테스트 실행(소유자). 기존
PASS 70 / FAIL 0이 떨어지지 않는지 먼저 확인 moments_region_2nd_rel_invar→moments_region_3rd계열 (함정 #5 부호 규약이 3차 홀수항에서부터 실제로 값을 바꾼다. 2차는 영향 없음 —02_DEFINITIONS.md§6.3)- HALCON 환경 확보 시 V2 실측으로
R-1·MI-1·EA-2·EC-1·HC-1·HC-3해소 roundness—elliptic_axis와 같은 윤곽/중심 캐시를 그대로 쓴다- ⚠ 재사용 공개 컨텍스트 API — 배치가 늘 때마다
ComputeFeatures→ComputeFeaturesAndMoments→ComputeFeaturesMomentsAndTopology로 묶음 함수 이름이 길어지고 조합이 늘고 있다. 4차 배치 전에 결론을 내야 한다. 설계만docs/05_USER_GUIDE.md§6.5 에 있고 미구현이다
최난도로 남겨둔 것: rectangularity(닫힌 수식 없음) · select_shape(63 feature 이름 체계의 근간) · runlength_features(LFactor 정의 모호)
| 문서 | 언제 읽는가 |
|---|---|
README.md |
프로젝트 첫 인상 |
CLAUDE.md (이 문서) |
작업 시작 전 필수 |
docs/00_OVERVIEW.md |
범위·원칙·함정 14건·40종 현황표 |
docs/01_ARCHITECTURE.md |
코드를 짜기 직전 (설계 제약과 패턴) |
docs/02_DEFINITIONS.md |
구현의 유일한 근거. 수식을 옮길 때 |
docs/03_VERIFICATION.md |
테스트를 짤 때, 값이 안 맞을 때 |
docs/04_IMPLEMENTATION_NOTES.md |
Phase 1 구현 결과·판정 근거·문서 보정 이력을 확인할 때 |
docs/reference/halcon13/ |
정의서에 없는 오퍼레이터를 새로 추가할 때 |