1. 프로젝트 목표
컴퓨터 비젼으로, 사용자가 입력하는 숫자(300*300픽셀)를 4개 인식, 기존에 설정된 패스워드와 일치하는 지 확인하는 로그인 시스템을 만든다.
- 프로그램 요구사항 분석:
- 숫자 이미지(28*28), 60,000개를 구글 사이트에서 불러와 머신러닝 후, 머신러닝 한 학습파라메타를 저장한다.
- 저장된 파라메타를 불러들여서 입력한 손글씨의 숫자를 인식하게 한다.
- 입력은 웹캠으로 입력받으며 4각형 안에 손으로 쓴 손글씨를 캡쳐하는 방식으로 4번 반복한다.
- 성공하면 웹캠화면은 사라지고 웹서버의 특정 페이지를 로딩해서 보여준다.
- 실패 1회, 2회 남음을 알려주고, 실패 2회면 1회 남음을 알려준 후, 3회 실패시 10분동안 캡쳐가 안되도록 한다.
- 프로젝트 발표 및 준비사항 분석:
- PPT준비
- 동영상 저장
- youtube링크
- git hub에 링크
- 발표 시간 10분 이내
2. Dev 환경 설정
2.1. GitHub에서 리포지토리 생성
가장 먼저 원격 저장소를 만든다.
- GitHub에 로그인 후 New Repository 클릭.
- Repository Name 입력 (예:
OpenCV_Project02). - Public/Private 설정.
- 중요:
Initialize this repository with a README,.gitignore,License항목은 체크하지 않는다. (이미 로컬에 코드가 있으므로 충돌 방지를 위해 빈 저장소로 시작하는 것이 좋다.) - OpenCV를 사용했으므로 OpenCV의 라이센스인 Apache 2 License로 라이센스 설정했다.
- 생성 후
https://github.com/jalanwang/OpenCV_Project02.git형태의 URL을 복사해 둔다.
2.2 WSL에서 VS Code 실행 및 환경 확인
Windows 탐색기나 CMD가 아닌, WSL 터미널에서 VS Code를 열어야 한다.
- WSL 터미널을 실행하고 프로젝트 폴더로 이동.
cd ~/work/OpenCV_Project01
- VS Code 실행
code .
- VS Code 좌측 하단에 Checking Remote 혹은 WSL: Ubuntu라고 표시되어 있는지 확인한다.

6. 가상환경 복사
가상 환경을 그대로 복사해서 사용하려고 했는데 폴더 및 파일의 절대 및 상대 경로로 지정된 주소를 가지므로 다시 깔아주어야 한다.
2.3. Git 초기화 및 환경 설정 (VS Code 터미널)
VS Code 내의 터미널(Ctrl + ~)을 열고 아래 명령어를 순차적으로 수행한다.
Git 사용자 설정 (최초 1회)
git config --global user.name "본인ID" git config --global user.email "본인이메일"
robot@kimsh:~/work/OpenCV_Project02$ git config --global user.name "jalanwang" robot@kimsh:~/work/OpenCV_Project02$ git config --global user.email "jalalwang@gmail.com" robot@kimsh:~/work/OpenCV_Project02$ ls -al total 2884 drwxr-xr-x 4 robot robot 4096 Jan 14 10:05 . drwxr-xr-x 7 robot robot 4096 Jan 14 09:57 .. drwxr-xr-x 6 robot robot 4096 Jan 14 10:05 .venv drwxr-xr-x 2 robot robot 4096 Jan 14 10:05 .vscode -rw-r--r-- 1 robot robot 2932438 Jan 13 16:27 my_first_DNN_model.keras -rw-r--r-- 1 robot robot 3281 Jan 14 10:01 show_me_your_password.php
초기화
git init
이 명령어를 치면 폴더 내에 .git 숨김 폴더가 생성된다.
robot@kimsh:~/work/OpenCV_Project02$ git init hint: Using 'master' as the name for the initial branch. This default branch name hint: is subject to change. To configure the initial branch name to use in all hint: of your new repositories, which will suppress this warning, call: hint: hint: git config --global init.defaultBranch <name> hint: hint: Names commonly chosen instead of 'master' are 'main', 'trunk' and hint: 'development'. The just-created branch can be renamed via this command: hint: hint: git branch -m <name> Initialized empty Git repository in /home/robot/work/OpenCV_Project02/.git/ robot@kimsh:~/work/OpenCV_Project02$ ls -al total 2888 drwxr-xr-x 5 robot robot 4096 Jan 14 11:44 . drwxr-xr-x 7 robot robot 4096 Jan 14 09:57 .. drwxr-xr-x 7 robot robot 4096 Jan 14 11:44 .git drwxr-xr-x 6 robot robot 4096 Jan 14 10:05 .venv drwxr-xr-x 2 robot robot 4096 Jan 14 10:05 .vscode -rw-r--r-- 1 robot robot 2932438 Jan 13 16:27 my_first_DNN_model.keras -rw-r--r-- 1 robot robot 3281 Jan 14 10:01 show_me_your_password.php
2.4. .gitignore 파일 생성 (C++ 필수)
C++ 빌드 부산물(실행 파일, 오브젝트 파일 등)이 업로드되지 않도록 프로젝트 루트에 .gitignore 파일을 만들고 아래 내용을 추가한다. C/C++와 Python 모두 공통으로 사용해되 되는 .gitignore 파일이다.
파일명: .gitignore
# ------------------------------------------------ # Editor & System # ------------------------------------------------ .vscode/ # 협업 시 공유해야 하는 설정이 있다면 아래처럼 예외 처리(!) 가능 # !.vscode/launch.json # !.vscode/tasks.json # Workspace files *.code-workspace # ------------------------------------------------ # C/C++ Build Artifacts # ------------------------------------------------ # Object files *.o *.obj # Libraries *.lib *.a *.dll *.so *.dylib # Executables *.exe *.out *.app # Build Directories (CMake 등을 쓸 때 주로 생성되는 폴더) build/ bin/ **/bin/ # ------------------------------------------------ # Python # ------------------------------------------------ # Byte-compiled / Optimized / DLL files __pycache__/ *.py[cod] *$py.class # Virtual Environments .venv/ venv/ ENV/ # ------------------------------------------------ # Data & Logs (Whitelist 방식 권장) # ------------------------------------------------ *.csv *.log # *.txt와 *.json을 무시하되, 필수 설정 파일은 추적하도록 예외 처리 *.txt !CMakeLists.txt !requirements.txt *.json !package.json # 필요한 경우 특정 json 설정 파일 추가 예외 처리 (!settings.json 등) # ------------------------------------------------ # Self-configuration (Do NOT ignore) # ------------------------------------------------ # .gitignore 파일 자체는 목록에 넣지 않음
2.5. 원격 저장소 연결 및 첫 푸시
이제 로컬 Git과 GitHub를 연결한다.
- 스테이징 및 커밋
git add . git commit -m "Initial commit: OpenCV Project02 setup"
- 브랜치명 변경 (관례상 main 사용)
git branch -M main
- 원격 저장소 연결 (아까 복사한 URL 붙여넣기)
git remote add origin https://github.com/jalanwang/OpenCV_Project02.git
- 푸시(Push)
robot@kimsh:~/work/OpenCV_Project02$ git push -u origin main Username for 'https://github.com': jalanwang Password for 'https://jalanwang@github.com': remote: Invalid username or token. Password authentication is not supported for Git operations. fatal: Authentication failed for 'https://github.com/jalanwang/OpenCV_Project02.git/'
PAT라는 토큰을 만들어서 들어가는 것을 잊었다. 저장해 놓은 토큰을 꺼내와서 패스워드에 입력했다.
robot@kimsh:~/work/OpenCV_Project02$ git push -u origin main Username for 'https://github.com': jalanwang Password for 'https://jalanwang@github.com': Enumerating objects: 5, done. Counting objects: 100% (5/5), done. Delta compression using up to 12 threads Compressing objects: 100% (5/5), done. Writing objects: 100% (5/5), 2.48 MiB | 6.45 MiB/s, done. Total 5 (delta 0), reused 0 (delta 0), pack-reused 0 To https://github.com/jalanwang/OpenCV_Project02.git * [new branch] main -> main branch 'main' set up to track 'origin/main'. robot@kimsh:~/work/OpenCV_Project02$
2.6 확인

3. 소스코드
이 프로젝트는 전략 패턴(Strategy Pattern)을 기반으로 설계되어 있다. 즉, main 함수가 구체적인 구현 내용을 알 필요 없이, 인터페이스만으로 다양한 알고리즘(게임 모드)을 교체하며 실행하는 구조다.
3.1 모듈별 기능
- console.py
- 프로그램의 진입점이다.
WebcamManager를 초기화하고, 네비게이션 메뉴를 이용해서 사용자와 대화한다.
- show_me_your_password.py
- 사용자가 보여주는 이미지를 읽고, 이를 저장해서 리턴하는 함수이다.
- def get_password_image(): # 이미지를 사용자가 직접 캡쳐해서 넘겨주는 펑션이다.
- def get_password_image(2): # 사용자에게 가이드라인을 제공해서 이미지를 캡쳐하는데 도움을 주는 펑션이다.
- login.py & login2.py
- 로그인을 위해서 이미지 캡쳐 파일을 불러 들여, 패스워드와 비교하는 루틴이다.
- login.py: def get_password_image(): 모듈을 이용해서 로그인한다.
- login.py: def get_password_image2(): 모듈을 이용해서 로그인한다.
- machine_learning.py
- 핸드라이팅 이미지(7만장)을 불러들여 머신 러닝을 수행하는 코드다.
- 머신 러닝 후, 학습된 파라미터와 출력뉴런을 저장하고 있는 인공지능 모델이다.
- my_first_DNN_model.keras를 생성한다.
3.2 하드웨어
WebcamManager.hpp(Driver/Adapter)- OpenCV의
VideoCapture클래스를 래핑(Wrapping)한 클래스다. - 카메라 장치 열기, 해상도 설정, 프레임 획득 같은 하드웨어 I/O 로직을 캡슐화해서 다른 코드들이 OpenCV API에 직접 의존하지 않토록한다.
- OpenCV의
3.3 핵심 엔지의 개선 과정 및 결과
- padding 추가


- 바운딩 박스의 제시

- 바운딩 박스의 일정 크기 담보

4. 수학 및 머신러닝
이 프로젝트는 미적분학, 선형대수학, 위상수학, 통계학이라는 네 가지 수학적 기둥 위에 설계된 OpenCV API를 이용해서 구축되었다. 소스코드의 각 모듈이 어떤 수학적 원리를 바탕으로 작동하는지 여기서 확인 할 수 있다.
5.1. 미적분학 (Calculus): 움직임과 밀도
- 미분 (Differentiation) – RedBallGame
움직임(Motion)을 감지하기 위해 시간($t$)에 따른 픽셀 밝기($I$)의 변화율을 계산해. 연속된 프레임 간의 차이는 시간에 대한 편미분의 근사치다.
$$\frac{\partial I}{\partial t} \approx | I_t(x,y) – I_{t-1}(x,y) |$$
- 적분 (Integration) – TransformGame
충돌 감지는 단순히 좌표가 겹치는 것이 아니라, 유효 영역($R$) 내부의 움직임 밀도(Density)를 적분하여 판단해. 이는 노이즈로 인한 오작동을 방지하는 강건한(Robust)한 설계다.
$$S = \iint_{R} M(x,y) \,dx\,dy$$
5.2. 머신러닝
- 신경망 모델 구성
# 신경망 모델 구성
model = keras.Sequential([
keras.layers.Input(shape=(28, 28)), #입력층: 28x28 크기의 2차원 배열임
keras.layers.Flatten(), #28x28 2차원 배열을 784 1차원 배열로 변환. 뉴런 연결을 위해 필요
keras.layers.Dense(1024, activation='relu'), #뉴런 활성화는 relu 사용
keras.layers.Dense(512, activation='relu'), #뉴런 활성화는 relu 사용
keras.layers.Dense(256, activation='relu'), #뉴런 활성화는 relu 사용
keras.layers.Dense(128, activation='relu'), #뉴런 활성화는 relu 사용
keras.layers.Dense(64, activation='relu'), #뉴런 활성화는 relu 사용
keras.layers.Dense(10, activation='softmax') #출력이 2개 이상에서는 softmax 사용
])
- 학습
model.fit(train_images, train_labels, epochs=5) #모델 학습. 5회 반복
- 저장
model.save('my_first_DNN_model.keras') #모델 파일명 지정하여 저장
6. 관련자료
6.1 Release 페이지
https://github.com/jalanwang/OpenCV_Project02/releases/tag/v1.0.0

6.2 동영상
6.3 본 문서의 위치
https://coffeecrawlers.com/?p=2176
6.4 구글슬라이드
6.5 학습 및 관련 도구
- Karl 선생님 수업 자료
- OpenCV 4로 배우는 컴퓨터 비전과 머신 러닝, 황선규, 길벗, 초판 10쇄
- 데이터 과학을 위한 파이썬 머신러닝(IT COOKBOOK), 최성철 , 한빛아카데미(교재)
- QR 코드 생성기: https://qr.naver.com/
- Git CLI: https://learngitbranching.js.org/?locale=ko
