초기 커밋.

This commit is contained in:
2026-02-03 11:33:58 +09:00
parent 90b3415a1f
commit b6b823b1c4
71 changed files with 4794 additions and 0 deletions

91
ProjectAnalysis.md Normal file
View File

@@ -0,0 +1,91 @@
# LPR_Manager 프로젝트 분석 보고서
## 1. 개요
- **목적**: 다차선 주차장 번호판 인식 결과를 실시간으로 모니터링하고, 카메라/LED/차단기를 통합 제어하는 WPF 클라이언트.
- **플랫폼**: .NET 8 WPF (`net8.0-windows`), MaterialDesign XAML 테마, CommunityToolkit.Mvvm 기반 MVVM 구조.
- **주요 의존성**: `OpenCvSharp4`/`WpfExtensions`(영상 처리), `Serilog`(로그), `Microsoft.AspNetCore.App`(내장 이미지 서버), 외부 네이티브 SDK `NtcClientAPI4Net.dll`, 사내 라이브러리 `Inno.LPR`.
- **구조 요약**: `View`/`ViewModel`/`Model`/`Service`/`Protocol` 계층으로 분리, Lane 단위를 중심으로 한 ObservableCollection 관리.
## 2. 계층별 구성
### UI (XAML)
- `MainWindow.xaml`: 좌측 네비게이션 + 상단 상태바 + 탭 기반 콘텐츠. 대시보드 탭은 `LprLaneControl` 반복, 나머지는 Placeholder UI.
- `View/LprLaneControl.xaml`: 단일 차선 카드. 카메라 스트림, 인식 번호판, 상태 Pill, 최근 로그 DataGrid 등으로 구성.
- `View/SettingsControl.xaml`: 시스템/차선 설정 편집 UI. Lane 목록과 상세 편집 폼을 하나의 뷰로 처리.
- `View/LoginWindow.xaml`, `View/SplashScreen.xaml`: 로그인 및 초기 스플래시 UX.
### ViewModel & 상태 관리
- `ViewModel/MainViewModel.cs`: 전역 상태, Lane 목록, 설정 및 인증 흐름을 담당.
- 앱 시작 시 `InitializationTask`에서 설정 로드 → 이미지 서버 기동 (`Service.ImageServer`) → Lane ViewModel 생성/초기화.
- `System.Threading.Timer`로 UI 타임스탬프, 세션 타이머, 이미지 서버 상태를 1초 주기로 갱신.
- Lane 추가/저장/삭제, 시스템 설정 저장, 로그인/로그아웃 Command 제공.
- `ViewModel/LprLaneViewModel.cs`: 카메라/인식/LED/CMS 제어에 대한 핵심 로직.
- `WushiCamera` SDK 이벤트를 받아 OpenCvSharp로 영상 디코딩/번호판 탐지/인식 수행.
- Serilog Logger를 Lane별로 구성하여 파일 혹은 Seq 출력.
- 인식 결과를 UI 속성 및 `OnCarDetected` 이벤트로 전달하고, 로컬 이미지 저장/추후 CMS 전송 준비.
### Services
- `Service.ConfigService`: `Configs/` 폴더에 Lane 및 시스템 설정을 JSON 으로 직렬화/역직렬화.
- `Service.ImageServer`: Minimal API (`WebApplication`)로 구동되는 정적 파일 서버. `/images/*` 경로를 Basic Auth 로 보호.
- `Service.LogService`: 전역 Serilog 싱크 구성(파일/Seq).
- `Service.WushiCamera`: `NtcClientAPI4Net.dll` P/Invoke 래퍼. 카메라 연결 및 트리거 콜백 처리.
### Device & Protocol Layer
- `Model/Device/*`: Gate/LED/CMS 컨트롤러 인터페이스 + 기본 구현. 현재 TCP 커넥터 부분은 주석 처리되어 있으며, 프로토콜 패킷 조합만 남아 있음.
- `Protocol/*`: LED(UJIN, YJMICRO), Gate(FPTV1), CMS(InnoV1) 규격 문자열/바이트 생성 및 파싱 함수.
- `Model/Device/SubClass/*`: CMS/LPR 데이터 전송 DTO, LED 텍스트 세트 등 부가 모델 정의.
## 3. 실행 흐름 요약
1. `App.OnStartup` (`App.xaml.cs`)
- `ConfigService`로 시스템 설정 로드 → `LogService` 설정.
- 메인 윈도우를 표시한 뒤 스플래시를 메인 중앙에 띄우고 `MainViewModel.InitializationTask` 또는 10초 타임아웃을 기다림.
2. `MainViewModel.InitializeSystemAsync`
- 이미지 서버 (`Service.ImageServer`)를 `SystemConfig` 기반으로 기동.
- Lane 설정을 로드하고 없으면 기본 Lane 생성/저장.
- 각 Lane마다 `LprLaneViewModel` 생성 → `InitializeAsync`로 카메라 연결 및 엔진 준비.
3. `LprLaneViewModel`
- `WushiCamera.OnImageReceived` 이벤트에서 JPEG 버퍼를 OpenCV `Mat`으로 디코드 → 번호판 박스 탐지 → 사용자가 지정한 정렬 기준으로 우선순위 결정.
- 정상 판독 시 UI 상태, 로그, `ProcessDetection` 호출, 이미지 파일 저장.
- CMS/LED/Gate 제어 부분은 주석/스텁으로 남아 있어 확장 여지 존재.
## 4. 데이터 & 설정 파일
- `Configs/system_config.json`: 이미지 서버 포트/자격증명, 이미지 저장 경로, 로그 모드.
- `Configs/*.json`: Lane 별 카메라/CMS 설정 (동적으로 생성).
- `Logs/`: Serilog 및 `WushiCamera` 로그, Lane별 로그.
- 이미지 저장 경로: `SystemConfig.ImageRootPath` (기본 `Images/`). 날짜/차선 단위 폴더 구조로 저장.
## 5. 개선이 필요한 부분 (우선순위 순)
1. **잘못된 바인딩 / 누락된 속성**
- `MainWindow.xaml:92`에서 `SessionTimeRemaining`(문자열)을 `BooleanToVisibilityConverter`에 그대로 바인딩하여 런타임 예외가 발생. 표시 여부를 위한 bool 속성을 별도로 두거나 `StringIsNullOrEmpty` 변환기를 구현해야 함.
- `View/LprLaneControl.xaml:91``LastDetectionTime`에 바인딩하지만 `LprLaneViewModel`에 해당 속성이 전혀 없음. 인식 시점 추적용 속성을 추가하고 `Camera_OnImageReceived`에서 갱신해야 함.
2. **리소스 해제 부재**
- `MainViewModel``LprLaneViewModel``System.Threading.Timer`와 네이티브 카메라 핸들을 생성하지만 `IDisposable`을 구현하지 않아 윈도우를 닫아도 백그라운드 스레드와 네이티브 리소스가 남음 (`MainWindow.xaml.cs`는 종료 훅도 없음).
- `Service.ImageServer``StartAsync`만 호출하고 애플리케이션 종료 시 `StopAsync`를 호출하지 않음. Graceful shutdown 경로를 추가해야 포트가 해제됨.
3. **동기식/무제한 영상 처리** (`ViewModel/LprLaneViewModel.cs:210` 이후)
- 카메라 SDK 콜백에서 OpenCV 처리와 WPF `Dispatcher.Invoke`가 연쇄적으로 실행되어 콜백 쓰레드가 블로킹되고 GC 압박이 큼. CPU 집약 작업을 전용 `Task.Run` 파이프라인으로 분리하고, UI 접근은 `Dispatcher.BeginInvoke`로 최소화할 필요가 있음.
- 인식 실패 시에도 모든 박스를 순회하므로 고주파 입력에서 backlog가 쉽게 발생. 프레임 드랍/율 제한이 필요.
4. **하드코딩된 인증 정보 및 보안 취약점**
- `View/LoginWindow.xaml.cs`에 관리자 ID/비밀번호가 평문으로 고정되어 있으며 시도 횟수 제한도 없음. 구성 파일 또는 외부 인증과 연동하고 암호는 해시로 비교하도록 변경 필요.
- `Service.ImageServer`는 HTTP + Basic Auth를 사용하지만 TLS가 없고 비밀번호가 `Configs/system_config.json`에 평문 저장됨. 최소한 HTTPS(개발 인증서)와 암호 해싱/암호화, 혹은 내부망 한정이라는 주석/문서가 필요.
5. **설정값 미사용**
- `LprLaneViewModel.InitializeAsync`에서 카메라 로그인 정보를 `_config` 대신 하드코딩(`admin` / `Inno!@#$5678`)으로 넘김. 설정 UI에서 값을 바꿔도 실제 카메라에는 적용되지 않음.
- `RecognitionArea` 문자열, `UseSingleShot`, CMS/LED 관련 설정이 실제 로직에 연결되어 있지 않아 UI/Config와 동작 간 괴리가 큼.
6. **저장 이미지 경로 처리 오류**
- `ProcessDetection`에서 CMS로 넘기는 `ImagePath`가 항상 플레이스홀더 문자열이라 실제 저장 경로를 외부 시스템이 참조할 수 없음 (`ImageRootPath`를 기준으로 상대/절대 경로를 반환해야 함).
- `SaveRecognitionImage`는 WPF UI 스레드에서 `RenderTargetBitmap`를 생성하므로 고해상도 프레임 처리 시 UI 프리즈가 발생. 비 UI 스레드 인코딩 또는 WriteableBitmap → JPEG 변환 파이프라인으로 교체 필요.
7. **예외 및 복구 전략 부족**
- `MainViewModel.InitializeSystemAsync``Task.Run` 내부에서 예외를 삼키고 상태만 "Error"로 바꾸지만 사용자에게 구체적 원인을 표시하지 않으며 재시작 버튼도 없음.
- `WushiCamera.Start` 호출 실패 케이스(핸들 null, 반환 코드) 미검증. 연결 재시도 로직 필요.
8. **테스트/운영 편의성**
- Lane 구성이 파일로만 존재하여 UI 없이도 배포 환경에서 초기 Config를 넣기 어렵고, 버전 관리도 힘듦. 샘플 config와 Schema 설명 문서가 필요.
- `Inno.LPR` 프로젝트 및 네이티브 DLL 에 대한 빌드/배포 가이드가 없음 (README 미제공).
## 6. 권장 후속 작업
1. **ViewModel 정비**: `LprLaneViewModel``LastDetectionTime` 및 bool 노출 추가, `RecognitionArea` 파싱/적용, 카메라 인증 정보/이미지 경로 반영.
2. **리소스 & 수명 주기 관리**: `MainWindow` 종료 시점에 Lane VM/이미지 서버/Timer/카메라를 명시적으로 Dispose. `App.xaml.cs` 혹은 `MainViewModel``IDisposable` 구현 권장.
3. **영상 처리 파이프라인 개선**: 카메라 콜백에서 Frame Buffer를 채널로 넘기고, 전용 Task에서 OpenCV 및 저장 처리, UI 업데이트는 최소화. FPS 제한·중복 판독 Debounce 도입.
4. **보안 강화**: 로그인 절차를 Config 기반 혹은 사내 인증 연동으로 교체, 이미지 서버에 HTTPS/TLS 적용 및 비밀번호 암호화, Config 파일 접근권한 가이드 문서화.
5. **운영 도구화**: Config 폴더 구조/필드 설명, 샘플 JSON, 배포 스크립트, 로그 경로 정리 등을 README 또는 위키에 문서화.
6. **CMS/LED/Gate 통합 마무리**: 현재 주석으로 남아있는 TCP 커넥터 부분(`Model.Device`)과 `Inno.LPR` 결과 연동을 구현하여 실제 하드웨어 제어까지 닫기.
---
이 문서는 `D:/Documents/Projects/Parking/Center/LPR_Manager/LPR_Manager` 기준 소스(2026-02-02) 상태를 바탕으로 작성되었습니다.