# ANT 비전 검사 시스템 — 프로젝트 컨텍스트 > 최종 갱신: 2026-05-13 --- ## 1. 프로젝트 구조 및 파일 목록 ``` E:\ANT\ ├── main.py # 엔트리포인트 (스플래시 → 백그라운드 초기화 → MainWindow) ├── logger.py # 로그 시스템 (app/inspect/timing/train CSV) ├── find_cells_trigger.py # Cognex 셀 전체 스캔 유틸 (진단용) ├── config.json # 런타임 설정 저장 (cognex/basler/db/ai/conveyor/plc) │ ├── camera/ │ ├── insight.py # InSightCamera — Telnet + FTP 영구세션 │ └── basler.py # BaslerCamera — pypylon SDK │ ├── db/ │ ├── sql_client.py # SQLClient — MS SQL Server (pyodbc, ODBC Driver 18) │ └── mysql_client.py # MySQLClient — 미사용 레거시 (pymysql) │ ├── ai/ │ ├── detector.py # Detector — YOLOv8 추론 (ultralytics) │ └── trainer.py # Trainer + TrainWorker — 재학습 (별도 subprocess) │ ├── logic/ │ ├── inspector.py # Inspector — PatMax 결과 판독 + 모델 판별 + Pass/Fail │ ├── group_manager.py # GroupManager — A/B 그룹 수동 전환 (최대 4종) │ └── pattern_matcher.py # PatternMatcher — ORB 특징점 + 엣지 NCC fallback │ ├── plc/ │ └── plc_client.py # PLCClient — 인터페이스만 정의 (미구현) │ ├── gui/ │ ├── main_window.py # MainWindow — 4탭 네비게이션, 상태바 │ ├── splash_screen.py # SplashScreen + InitWorker │ ├── image_settings_dialog.py # 이미지 설정 다이얼로그 │ └── pages/ │ ├── settings_page.py # 환경설정 탭 (연결카드 + 관리자 설정 다이얼로그) │ ├── register_page.py # 제품 등록 탭 (MES 불러오기 + 캡처) │ ├── inspect_page.py # 검사 탭 (파이프라인 워커 + 결과 표시) │ └── retrain_page.py # 재학습 탭 (YOLOv8 재학습 UI) │ ├── assets/ │ ├── images/ant_logo.png │ └── patterns.pkl # PatternMatcher 등록 패턴 저장 파일 │ └── logs/ ├── app/YYYY-MM-DD.log # 전체 앱 로그 (print 가로채기) ├── inspect/YYYY-MM-DD.csv # 검사 결과 CSV └── timing/YYYY-MM-DD.csv # Cognex/Basler 타이밍 CSV ``` --- ## 2. 확정된 셀 주소 (Cognex GV 방식) `logic/inspector.py` `PATTERN_RESULT_CELLS` 딕셔너리에 확정: | 셀 주소 | ID | 제품명 | 모델 | Type | |---------|-----|--------|------|------| | **A27** | 1 | LOW REF | LX3 | RH | | **A77** | 2 | LOW REF | LX3 | LH | | **A127** | 3 | LOW REF NAS | LX3 | RH | | **A177** | 4 | LOW REF NAS | LX3 | LH | - 읽기 방식: `GV{셀주소}` 전송 → 응답 `"1"` + 값 라인 수신 - 값 파싱: `"(736.1,742.0) -1.8 = 82.9"` 형식에서 `=` 뒤 점수 추출 - `#ERR` 포함 시 → matched=False, score=0.0 > Cognex 인식 외 추가 제품은 `PatternMatcher` (Python ORB/NCC) 경로로 처리 --- ## 3. DB 접속 정보 **드라이버**: `ODBC Driver 18 for SQL Server` (pyodbc) **연결 문자열 구조** (`db/sql_client.py`): ``` DRIVER={ODBC Driver 18 for SQL Server}; SERVER=<서버주소,포트>; DATABASE=; UID=<사용자명>; PWD=<비밀번호>; TrustServerCertificate=yes; Encrypt=optional; ``` **설정 UI 예시 서버 주소**: `Wizis.iptime.org,20220` **사용 뷰/테이블**: - `vi_AI_mt_Article` — 제품 등록 탭에서 리플렉터 목록 조회 ```sql SELECT ArticleID, Article, BuyerArticleNo FROM vi_AI_mt_Article WHERE Article LIKE '%REF%' ORDER BY ArticleID ``` **설정 저장 위치**: `config.json` → `"db"` 키 (server/database/username/password) **자동 연결**: 앱 시작 시 `MainWindow._auto_connect_db()` 가 config.json 값으로 자동 시도 --- ## 4. 구현 완료된 기능 ### 카메라 - [x] Cognex In-Sight — Telnet 로그인 (admin/빈 비밀번호) - [x] Cognex In-Sight — FTP 영구세션 (NOOP keepalive + 자동 재연결) - [x] Cognex In-Sight — SE8 소프트웨어 트리거 - [x] Cognex In-Sight — FTP BMP 우선 / JPG fallback 이미지 수신 - [x] Basler USB — pypylon GrabOne 단일 캡처 - [x] Basler USB — ExposureAuto=Continuous 연결 - [x] Basler USB — 연속 grab (start_continuous / grab_latest) ### 검사 로직 - [x] Cognex GV 방식 PatMax 결과 조회 (A27/A77/A127/A177) - [x] Python PatternMatcher — ORB 특징점 매칭 (Lowe's ratio test 0.75) - [x] Python PatternMatcher — 엣지 NCC fallback (특징점 10개 미만 시) - [x] PatternMatcher — ORB+NCC 혼합 결과 병합 - [x] 모델 판별 (최고 점수 패턴 선택 → 허용 그룹 여부 확인) - [x] Pass/Fail 최종 판정 (cognex_pass AND basler_pass) - [x] 그룹 A/B 수동 전환 (최대 4종 per 그룹) ### 검사 파이프라인 (InspectWorker) - [x] Cognex 트리거 → 1초 대기 → FTP 수신 → PatMax 병렬 처리 (서브스레드) - [x] Basler 캡처 — 트리거 기준 belt_delay 후 촬영 (동시 진행) - [x] YOLOv8 추론 — 불량 감지 (confidence ≥ 0.5) - [x] 검사 결과 카운터 — 그룹별 전체/양품/불량/미인식 ### AI - [x] YOLOv8 모델 로드/해제 (지연 로딩 — torch DLL 충돌 방지) - [x] 4클래스 추론: 스크래치/이물/흑점/변형 - [x] 재학습 — 데이터셋 준비 (80/20 train/val 자동 분할) - [x] 재학습 — YOLOv8n 기반, 별도 subprocess 격리 (Qt 충돌 방지) - [x] 재학습 — 에포크별 진행 콜백 → UI ProgressBar 연동 ### GUI - [x] 1920×1080 전체화면, 다크 테마 - [x] ChevronTabButton — breadcrumb 스타일 4탭 (환경설정/제품 등록/검사/재학습) - [x] 재학습 탭 더블클릭(600ms) → 창 최소화 단축 - [x] 환경설정 탭 — 연결 카드 (코그넥스/Basler/DB/AI) - [x] 관리자 설정 다이얼로그 — 6탭 (코그넥스/Basler/DB/AI모델/컨베이어/PLC) - [x] 관리자 인증 — 4자리 PIN 키패드 (기본값: 1234) - [x] 제품 등록 탭 — MES 불러오기 (DB 연결 시 활성화) - [x] 제품 등록 탭 — In-Sight 트리거 캡처 + 미리보기 - [x] 검사 탭 — Cognex/Basler 듀얼 영상 표시 - [x] 검사 탭 — Basler 이미지에 불량 BBox 오버레이 (클래스별 색상) - [x] 상태바 — 코그넥스/Basler/DB 연결 상태 실시간 표시 - [x] 컨베이어 딜레이 설정 — 거리(cm) ÷ 속도(cm/s) 자동 계산 ### 로그 - [x] print 가로채기 — 타임스탬프 자동 prefix + 파일 저장 - [x] 세션 시작/종료 헤더 (비정상 종료 감지 포함) - [x] 검사 결과 CSV (`logs/inspect/`) - [x] 카메라 타이밍 CSV (`logs/timing/`) - [x] 사용자 액션 강조 로그 --- ## 5. 미구현 / 블로킹 기능 ### 블로킹 (핵심 미완성) | 항목 | 파일 | 상태 | |------|------|------| | 검사 결과 DB 저장 | `db/sql_client.py:save_inspection_result()` | TODO — 저장 테이블 미확정 | | PatternMatcher 등록 UI 연동 | `gui/pages/register_page.py` | 캡처만 구현, `matcher.train()` 호출 없음 | | PatternMatcher 등록 저장 버튼 | `gui/pages/register_page.py` | 미구현 | ### 미구현 (인터페이스만 정의) | 항목 | 파일 | 상태 | |------|------|------| | PLC 통신 전체 | `plc/plc_client.py` | 통신 방식 미확정 (Modbus TCP / MC프로토콜 / OPC-UA 중 선택 필요) | | PLC 연결 버튼 | `gui/pages/settings_page.py:_build_tab_plc()` | print만 출력 | | DB 리플렉터 등록/갱신 | `db/mysql_client.py:save_reflector()` | `pass` | | 재학습 후 모델 자동 교체 | `gui/pages/retrain_page.py` | 미확인 | ### 부분 구현 | 항목 | 상태 | |------|------| | Basler 노출/게인 설정 | UI만 있음, 연결 후 `ExposureAuto=Continuous` 고정 | | 제품 등록 탭 RH/LH 방향 표시 | DB `type` 필드가 비어있어 화살표 미표시 | --- ## 6. 시스템 흐름 요약 ### 앱 시작 ``` main.py └─ SplashScreen + InitWorker (백그라운드) ├─ InSightCamera.connect() → Telnet + FTP 세션 ├─ BaslerCamera.connect() → pypylon ├─ config.json 로드 └─ MainWindow(insight, basler, config) ├─ PatternMatcher.load() → assets/patterns.pkl ├─ SQLClient 자동 연결 → config.json db 설정 └─ Detector (모델 미로드 상태) ``` ### 검사 1사이클 (InspectWorker.run) ``` [메인 루프] │ ├─ [Cognex 서브스레드] ─────────────────────────────────────┐ │ SE8 트리거 전송 │ │ → sleep(1.0) │ │ → FTP get_image() (BMP/JPG) │ │ → cognex_image_ready.emit(raw) ← GUI 표시 │ │ → inspector.read_patmax_results() ← GV 셀 조회 │ │ → inspector.match_image() ← Python ORB/NCC │ │ → cognex_out["results"] 저장 │ │ │ ├─ [워커 메인] belt_delay 대기 후 │ │ Basler.capture() │ │ → detector.detect() ← YOLOv8 추론 │ │ → basler_image_ready.emit(frame, detections) ← GUI │ │ │ ├─ ct.join(timeout=10.0) ← Cognex 서브스레드 완료 대기 ───┘ │ ├─ inspector.identify_model(results, allowed_ids) │ → 최고 점수 패턴 선택 → 허용 그룹 여부 확인 │ ├─ inspector.judge(cognex_pass, basler_pass) │ → "PASS" or "FAIL" │ └─ result_ready.emit(dict) → UI 카운터/결과 표시 + CSV 기록 ``` ### 모델 판별 우선순위 1. **Cognex GV 셀** (A27/A77/A127/A177) — job 파일 내 PatMax 결과 2. **Python PatternMatcher** (ORB 특징점 → NCC fallback) — 추가 등록 제품 두 결과를 병합하여 가장 높은 점수의 패턴을 최종 선택. ### 컨베이어 딜레이 계산 ``` belt_delay (초) = 카메라 간 거리(cm) ÷ 벨트 속도(cm/s) 기본값: 100cm ÷ 30cm/s = 3.33초 ``` ### 설정 저장 - 모든 설정은 `config.json` (프로젝트 루트)에 JSON으로 저장 - 앱 재시작 시 자동 로드 및 카메라/DB 자동 연결 시도 --- ## 7. 주요 의존성 | 패키지 | 용도 | |--------|------| | PyQt5 | GUI 프레임워크 | | pypylon | Basler 카메라 SDK | | ultralytics | YOLOv8 추론/학습 | | opencv-python | 이미지 처리, ORB, NCC | | pyodbc | MS SQL Server 연결 | | pymysql | MySQL (레거시, 미사용) | | numpy | 배열 처리 | | pyyaml | 학습 데이터셋 yaml 생성 |