Experience
경력기술서
상황 → 문제 → 선택 → 결과 순서로 적었습니다.
수치는 모두 측정 조건과 함께, 검증 상태는 있는 그대로 표시했습니다.
현직(i3System) 프로젝트는
고객사·납품명·세부 사양을 제외한 서술입니다.
각 항목의 상태 칩은 검증이 어디까지 갔는지를 뜻합니다.
- 실기기 검증실제 기기에서 검증까지 마친 것
- 게이트 통과빌드·테스트·자동 게이트는 통과했고 기기 재검증이 남은 것
01 · Current
i3System · 연구원
2026.05 — 현재
C++17 · OpenCV · FFmpeg · CUDA · Qt6 · Python
영상 처리 소프트웨어 R&D. 세 가지를 맡고 있습니다 —
파노라마 스티칭 엔진 신규 개발, i3System SDK 기능 개발과 유지보수,
그리고 차량용 WiFi 열상 카메라 애플리케이션.
파노라마 스티칭 엔진 개발
v0.1.0 · Stage 1–3 완료
C++17OpenCVFFmpeg
CUDAQt6CMake / vcpkg
상황
서로 다른 방향을 향한 고정 카메라 두 대의 동기화된 영상을 하나의 광각 파노라마 영상으로 변환하는
데스크톱 소프트웨어를, 요구사항 정의부터 설계·구현까지 담당했습니다.
문제
세 가지 요구가 서로 충돌했습니다.
- 시간적 안정성 — 프레임마다 정렬·이음매를 다시 계산하면 화면이 미세하게 떨립니다(플리커).
- 속도 — 1080p 두 장을 4K로 합성하면서 실용적인 처리량이 필요했습니다.
- 장시간 안정성 — 입력 길이와 무관하게 메모리가 한정되어야 했습니다.
선택
- “한 번 계산하고 얼린다”를 설계 원칙으로 삼았습니다. 정렬·이음매·색보정을 대표 구간에서 한 번만 계산해 카메라 프로파일(JSON)에 동결하고, 렌더링은 그 고정 파라미터만 사용합니다. 프레임별 재계산은 플리커의 근원이라 판단해 고품질 모드에서만 선택적으로 열어 두었습니다.
- 왜곡보정·투영·정렬 세 단계를 하나의 픽셀 단위 remap LUT로 합쳤습니다. 프레임당 remap 연산이 1회로 줄어 속도의 핵심 레버가 되었습니다. 이 불변식(렌더 잡당 LUT 빌드 1회)은 코드에
assert로 못박아 회귀를 막았습니다.
- 스트리밍 파이프라인 — 전체 영상을 메모리에 올리지 않고 디코드 → 처리 → 인코드를 프레임 단위로 연결했습니다.
- 기하 우선, ML은 보정만. 파노라마의 골격은 카메라 기하로 세우고 ML은 정밀 정렬·국소 워핑만 다듬도록 역할을 제한했습니다. ML이 픽셀을 생성하지 않게 한 것은 산업용 영상의 신뢰성 때문입니다.
결과
CPU 스티칭이 remap 연산에 묶여 있어 스레딩만으로는 약 12fps가 천장임을 먼저 측정으로 확인하고,
GPU가 진짜 레버임을 근거로 CUDA 경로를 구현했습니다.
엔진 경로별 벤치마크
| 엔진 경로 | FPS | Remap | Peak Mem |
| CPU 단일 스레드 | 10.6 | 81.0 ms | 1,736 MB |
| CPU 스레드 파이프라인 | 11.6 | 84.6 ms | 1,978 MB |
| CUDA + 스레드 | 68.1 | 13.2 ms | 1,831 MB |
측정 조건: 1080p×2 → 3640×1622, 워밍업 30프레임 후 270프레임 · 목표 기준 30fps
- remap 81.0ms → 13.2ms (6.2배), 전체 68fps — 목표 30fps의 2.3배.
- 108,000프레임(60분) 연속 렌더에서 작업 세트 1,802–1,825MB로 평탄(편차 1.3%) — 입력 길이와 무관한 한정 메모리 확인.
- 오버랩 영역 평균 재투영 오차 2px 이하(4K), 고정 파라미터 하에서 프레임 간 합성 결과 바이트 동일 — 합성 ground-truth 생성기와 골든 테스트로 검증.
- 1단계 인수 기준 8/8 통과, 테스트 55/56 통과(1건은 CPU 전용 빌드에서 정상 스킵).
- 이후 GPU/CPU 엔진 런타임 선택, 실시간 프리뷰, 프로젝트 저장·불러오기, CUDA 빌드 통합까지 반영해 v0.1.0.
직접 판단한 것
동기화 방식. 대상 영상에 유효 오디오가 없다는 사실을 확인하고, 표준적인 오디오 교차상관 동기화 대신
오버랩 영역의 프레임 간 모션 교차상관을 1급 경로로 채택했습니다. 오디오 방식은 나중에 끼워 넣을 수 있도록 인터페이스만 남겼습니다.
색보정 구조. 카메라별 스칼라 게인만으로는 오버랩을 맞출 수 없다는 점을 발견했습니다 —
센서마다 배율뿐 아니라 DC 오프셋이 다르기 때문입니다. 가중 곱합 구조는 가산 오프셋을 실을 수 없어,
오프셋을 동결된 캔버스 바이어스 이미지로 만들어 프레임당 1회 더하는 방식으로 풀었습니다.
렌더 엔진 변경을 두 줄로 최소화한 설계입니다.
i3System SDK 기능 개발 및 유지보수
게이트 통과
C++98 / 11 / 17Boost → std
MSVC 툴체인영상 처리 모듈회귀시험
상황
2016년부터 이어져 온 카메라 SDK와 그 하부 유틸 라이브러리(스레드·워커·직렬 통신 계열)를
맡아 현행 개발 환경으로 옮기고, 기능을 이어서 개발·유지보수하고 있습니다.
이미 배포된 바이너리를 쓰는 소비자가 있어 “옮기되 아무것도 달라지면 안 되는” 조건이 붙었습니다.
문제
- 지정된 구버전 툴셋이 현행 빌드 머신에 설치조차 되지 않아 재현 자체가 불가능했습니다.
- 외부 라이브러리(Boost) 의존이 코드 전반에 퍼져 있었습니다.
- 무엇보다, 옮긴 뒤 동작이 달라졌는지 확인할 방법이 없었습니다.
선택
동작 무변경을 눈으로 확인하는 대신 통과해야 할 게이트로 만들었습니다.
- 소스 호환 게이트 — 같은 헤더가 C++98·11·17 세 표준에서 모두 컴파일되는지 자동 검증. 하나라도 깨지면 이식분을 받지 않습니다.
- vtable/ABI 대조 게이트 — 이식 전후의 가상 함수 배치를 대조해 기존 바이너리 소비자가 깨지지 않음을 확인합니다.
- 출력 회귀시험 고정 — 이식 과정에서 드러난 컬러맵 불일치를 회귀시험으로 고정해 재발을 막았습니다.
- Boost 의존을 C++11 표준 라이브러리로 치환하고 툴셋·SDK를 현행 버전으로 올렸습니다. 인코딩 혼용과 절대경로 하드코딩도 함께 제거했습니다.
결과
영상 처리 모듈(잡음 저감·에지 강화 계열) 이식까지 게이트를 통과한 상태로 완료했습니다.
더불어 SDK 생태계 전체의 저장소 지도·브랜치 위상·모듈 의존성·리스크를 문서로 정리해,
이후 누가 들어와도 어디를 건드리면 무엇이 깨지는지 먼저 볼 수 있게 했습니다.
문서가 아니라 실측으로
레거시의 알려진 결함들을 문서에 적힌 대로 받지 않고 직접 재현해 실측으로 확인한 뒤 이식 범위를 정했습니다.
이미 고쳐졌다고 적혀 있으나 실제로는 남아 있는 것, 반대로 문서에 없지만 살아 있는 제약이 섞여 있었기 때문입니다.
차량용 WiFi 열상 카메라 프로젝트
실기기 검증
Python라즈베리파이ESP32
PySide6OpenCVWiFi 스트리밍
상황
차량에 장착되는 WiFi 열상 카메라의 제어·표시 애플리케이션을 맡고 있습니다.
싱글보드 컴퓨터에서 영상을 받아 화면에 띄우고, 주변 장치를 제어하고, 기록을 남기는 앱입니다.
문제
책상에서는 잘 되는데 장착하면 깨지는 문제들이었습니다.
- 전원을 끊었다 켜는 콜드부트에서 화면이 멈추거나 앱이 죽었습니다.
- 영상 파이프라인이 한 번 끊기면 스스로 복구하지 못했습니다.
- 장치 제어가 UI 스레드에서 돌아 조작하는 동안 화면이 멈췄습니다.
한 일
- 콜드부트 화면 멈춤·크래시를 수정하고, 파이프라인에 재시작 내성을 넣어 끊겨도 스스로 복구하도록 했습니다.
- 주변 장치(감마) 제어 호출을 UI 스레드 밖으로 분리해 조작 중에도 화면이 멈추지 않게 했습니다.
- 저장 매체 자동 마운트, 녹화 상태 오버레이, 배터리 탭을 추가했습니다 — 차량에서는 화면만 보고 지금 상태를 알 수 있어야 합니다.
- GUI를 현행 프레임워크로 다시 작성했습니다.
- 배포 스크립트를 만들어 실기기 반영을 반복 가능한 작업으로 바꿨습니다.
현장에서만 드러나는 것
여기서 고친 문제는 대부분 개발 PC에서 재현되지 않았습니다.
전원을 끊었다 켜는 순간, 이동 중에 끊기는 연결, 조작하면서 동시에 화면을 봐야 하는 상황 —
실제 장착 환경에서만 드러납니다.
“빌드가 통과했다”와 “차량에 올려서 돈다”를 같은 말로 쓰지 않게 된 계기였습니다.
이 사이트의 상태 칩을 실기 검증과 빌드 검증으로 나눠 표시하는 것도 그래서입니다.
02
Belle&Wise Studio · Software Engineer
2025.04 — 2025.12
Python · LangGraph · Go · AWS
LangGraphFastAPIAWSDynamoDB
문제
단일 에이전트가 모든 작업을 순차 처리해 2박 3일 일정 생성에 평균 3분이 걸렸고, 정보 정확도도 낮았습니다.
선택
LangSmith와 자체 구축한 그래프 state 스냅샷 추적으로 병목을 찾아,
데이터 수집 단계의 동기 API 호출이 idle 시간의 대부분임을 확인했습니다.
단일 그래프를 Subgraph 계층 구조로 바꿔 관리자 노드의 지시 생성 단계를 없애고,
수집을 비동기 병렬로 재구성했습니다.
GoAWS Lambda (ARM)
DynamoDBSQSGrafana
문제
같은 자원을 두고 예약·웨이팅·주문을 제각각 다른 서비스로 관리하던 불편함이 출발점이었습니다.
선택
세 가지를 하나의 “자원”으로 추상화한 통합 대시보드를 설계했습니다.
x86 → ARM 서버리스로 전환해 비용을 낮췄고, 동시 예약 충돌은 낙관적 락으로,
데이터 유실은 FIFO 큐로 막았습니다. Grafana로 실시간 모니터링을 붙였습니다.
결과
Lambda 실행 비용 20% 절감. 메모리 구성별 실측으로 최저 비용 구성을 골랐습니다.
교내 프로젝트로 시작한 것이 실제 외주 의뢰로 이어졌습니다.
개발 문화 도입
한 일
팀에 프로젝트 관리 환경이 없던 상태에서 이슈 템플릿·브랜치 규칙·문서화 기준을 도입해 정착시켰습니다.
03
Enois Lab · 대표
2025.12 — 현재
SaaS · AI 자동화
Sprintify — 프로젝트 관리 AI 자동화 SaaS
개발 중
문제
작은 팀일수록 프로젝트 관리에 쓸 사람이 없습니다. 관리가 일이 되는 역설을 자동화로 풀고자 창업했습니다.
결과
숭실대학교 슈퍼스타 창업경진대회 우수상(2025.12). 현재 개발 진행 중입니다.
Method
일하는 방식
위 사례들에서
실제로 지킨 순서
-
검증 장치를 먼저 만든다
합성 ground-truth 생성기와 골든 테스트를 코드보다 먼저 둡니다. 불변식은 assert로 못박습니다 — 렌더 잡당 LUT 빌드는 1회. 이후 결과물은 이 게이트를 통과하는지로 판정합니다.
-
측정으로 레버를 고른다
느리다고 바로 GPU를 붙이지 않습니다. CPU 스레딩의 천장(약 12fps)을 먼저 측정해 병목이 remap 연산임을 확인한 뒤에 CUDA로 갔습니다. 짐작으로 고른 최적화는 대체로 틀린 곳을 팝니다.
-
동작 무변경을 게이트로 만든다
“달라지지 않았다”를 눈으로 확인하지 않습니다. 소스 호환(C++98/11/17)과 vtable/ABI 대조를 자동 게이트로 세우고, 통과하지 못한 이식분은 받지 않습니다. 의도적인 동작 변경은 건건이 명시합니다.
-
다관점으로 훑고, 반드시 반증한다
여러 관점으로 훑어 나온 지적을 그대로 믿지 않습니다. 반증과 직접 재현을 통과한 것만 고칩니다 — 개인 프로젝트(OshiVerse)에서 스택을 8개 관점으로 검증했을 때 12건이 보고됐지만 살아남은 것은 6건이었습니다.
-
현장에서 도는 것만 “된다”고 말한다
빌드 통과와 실기기 동작을 구분해서 씁니다. 콜드부트 크래시나 이동 중 끊기는 연결은 개발 PC에서 재현되지 않습니다. 검증하지 못한 경로는 “검증 완료”로 쓰지 않고 후속 항목으로 남깁니다.
-
내가 만든 구멍은 내가 만든 구멍이라고 적는다
수정이 만든 2차 문제, 검증하지 못한 경로, 의도적으로 남긴 비대칭 — 전부 문서와 커밋 메시지에 명시합니다. 상태를 정확히 아는 것이 빠른 것보다 중요합니다.