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