
머신비전 장비에서 "이 렌즈가 정상이냐" 에 답하는 도구, 바로 렌즈 캘리브레이션 모듈입니다. 저희 장비에서 이걸 한 번 크게 손봤는데, 과정 자체가 좀 길어져서 한 편으로는 안 되겠더라구요. 7편짜리 시리즈로 나눠서 기록해 둡니다.
처음엔 "기존 모듈을 Cognex 로 통합하는 리팩토링" 으로 시작했는데, 진행하면서 상황이 바뀌었습니다. Cognex 의 검출 엔진과 구조적으로 호환되는 자체 OpenCV 검출기를 하나 만들었고, 지금은 두 검출기를 같은 엔진에 꽂아보며 어느 쪽이 장기적으로 더 나은지 고민하는 중입니다. 결정이 난 이야기가 아니라 "아직 결정 안 난" 이야기예요.
그래서 이 시리즈는 "이렇게 했습니다" 라는 완성형 튜토리얼이 아니고, "이런 고민을 하면서 이 구조를 만들었습니다" 에 가깝습니다. 중간중간 "이건 아직도 모르겠어요" 라는 말이 나올 거예요. 미리 양해 부탁드립니다.
시리즈 구성
| # | 제목 | 핵심 주제 |
|---|---|---|
| 1 | Cognex 정식 검출기 vs 자체 OpenCV 검출기, 아직 고민 중입니다 | 두 검출기를 같이 품고 있는 이유, 판단 기준, 현재까지 결과 |
| 2 | 검출기를 갈아끼울 수 있게 만든 설계 | 공통 결과 구조체 + 그리드 인덱스를 검출기가 책임지는 구조 |
| 3 | 체커보드에서 뽑아내는 기본 지표 5가지 | 해상도·등방성·9영역 균일도·중심-주변 편차 |
| 4 | 재투영 오차와 직교성 — 격자는 얼마나 반듯한가 | Similarity Transform, 직교성, 교차 진단표 |
| 5 | 텔레센트릭 렌즈에도 왜곡 측정이 필요한 이유 | 방사 왜곡 k1/k2, Michelson 콘트라스트, Sobel 샤프니스 |
| 6 | [Insight] 숫자보다 히트맵 — 현장에서 실제로 쓰이는 대시보드 만들기 | 4단 합성, 오버레이 레벨, 계층적 정보 전달 |
| 7 | [Insight] 아직 끝나지 않은 회고 | 결정 못 한 것들, 앞으로 해볼 것, 이 과정에서 배운 것 |
3편부터 6편까지는 검출기 선택과 독립적인 이야기입니다. 품질 지표와 시각화는 어느 검출기를 쓰든 그 위에 똑같이 올라갈 수 있으니까요. 그래서 검출기 고민이 아직 결정 안 난 상태에서도 이 부분은 안심하고 먼저 만들어 둘 수 있었습니다. 이게 이번 구조의 나름 괜찮은 점이기도 합니다.
대상 독자
- 머신비전 장비나 검사기를 직접 만드시는 분
- 상용 SDK (Cognex, Halcon 등) 와 자체 OpenCV 구현 사이에서 고민해보신 분
- "캘리브레이션 도구가 있긴 한데 현장에서 안 쓰인다" 는 경험이 있으신 분
- C++/MFC 기반 비전 툴을 유지보수하시는 분
기술 스택
- 언어: C++17, MFC
- 비전: OpenCV 4.x, Cognex VisionPro OCX (CogDisplay, CogCalibCheckerboard)
- 대상 렌즈: 텔레센트릭 렌즈 (이론상 왜곡 ≈ 0)
- 입력: 8bit grayscale 체커보드 이미지
- 테스트: 총 135 케이스 PASS (수학 검증용은 Cognex 의존 우회)
전체 그림
이미지 입력
│
▼
[검출기] ← 여기가 1~2편의 주제
├─ CCalibrationTarget (Cognex — HWTester 원본)
└─ CCalibrationTargetCV (자체 OpenCV 구현, 현재 기본)
↓
둘 다 CALIBRATION_TARGET_RESULT 반환
│
▼
[그리드 인덱스 맵] ← m_vGridMap[r][c]
│
▼
[스케일 계산] ← 3편
│
▼
[품질 분석 7종] ← 3, 4, 5편
│
▼
[대시보드 + PropertyGrid] ← 6편
"검출기 두 개가 같은 결과 구조체로 떨어진다" 는 점이 이 구조의 핵심입니다. 엔진 쪽 코드는 어느 검출기가 들어와도 그대로 돌아가요. 이걸 가능하게 만든 설계가 2편의 주제입니다.
그럼 다음 편부터 본론으로 들어가겠습니다.
반응형
'Vision & Inspection' 카테고리의 다른 글
| [LensCal] 검출기를 갈아끼울 수 있게 만든 설계 (0) | 2026.04.13 |
|---|---|
| [LensCal] Cognex 정식 검출기 vs 자체 OpenCV 검출기, 아직 고민 중입니다 (0) | 2026.04.13 |
| [Vision/C++] 반복 패턴 이미지에서의 Grid Center 검출 알고리즘 구현 (0) | 2025.12.21 |
| [C++/CUDA] 90GB 대용량 버퍼풀에서 4,000개 ROI만 쏙 뽑아 초고속 어파인 변환하기 (Zero-Copy & Batch Assembly) (0) | 2025.12.07 |
| [Insight] 이미지를 돌릴까, 마스크를 돌릴까? (Image vs Mask Rotation) (0) | 2025.12.07 |