프로젝트 개요
목록 | 내용 |
---|---|
프로젝트명 | Vision AI 기반 제조 자동화 검수 시스템 |
개발기간 | 2022년 10월 - 2022년 12월 (2개월) |
역할 | AI Solution 개발자 (직접 기획, 설계 및 구현) |
기여도 | 90% (1인 개발, 제조 담당자 데이터 검수 협업) |
개발환경 | 로컬 환경, 웹캠 4대, PyQt5 독립 실행 |
비즈니스 배경 및 문제 정의
핵심과제
커스터마이징 간편식 제조 과정의 스티커 라벨링 비효율성 및 옵션 누락 문제 해결
제조 환경:
- 4단계 제조 카운터: 용기 → 채소 → 옵션 → 포장 (사람이 카운터에서 단계별 진행)
- 커스터마이징 옵션: 개인 취향별 재료 제외 (당근X, 오이X 등)
- 일일 제조량: 100-200개 제품 생산
기존 프로세스 문제점:
- 스티커 라벨링 비효율성: 용기마다 개별 라벨 부착 작업으로 시간 소요
- 옵션 누락 빈발: 하루 100-200개 제조 시 옵션 누락 사례 다수 발생
- 수작업 카운팅 오류: 제조 담당자 수동 카운팅으로 인한 실수
- 복잡한 옵션 순서: 제조 목록 순서 추적 어려움으로 혼란 야기
- 네트워크 제약: 웹 기반 시스템 사용 불가한 제조 현장 환경
핵심 성과 지표
지표 | 달성값 | 측정 방법 |
---|---|---|
객체 탐지 정확도 | 0.65 → 0.8+ | mAP@0.5 기준 23% 성능 향상 |
실시간 처리 성능 | <1초 지연 | YOLOv5s + DeepSORT 최적화 |
다중 웹캠 지원 | 최대 4개 | 멀티스레딩 기반 병렬 처리 |
환경 적응성 | 제조 환경 변화 대응 | 조명, 재료 적재 상태 변화 robust |
기술 스택 및 아키텍처
핵심 기술 스택
# 주요 기술 구성
Object Detection: YOLOv5s # 경량화된 실시간 용기 탐지
Object Tracking : DeepSORT # 개별 용기 추적 및 ID 관리
Image Processing: OpenCV # 영상 처리 및 전처리
GUI Framework : PyQt5 # 독립 실행 데스크톱 앱
Deployment : Pyinstaller # .exe 패키징으로 로컬 대응
Data Processing : NumPy, Pandas
시스템 아키텍처
graph TD A[웹캠 영상 입력] --> B[YOLOv5s 객체 탐지] B --> C[DeepSORT 객체 추적] C --> D[중앙선 교차 감지] D --> E[방향성 카운팅] E --> F[제조 목록 매칭] F --> G[옵션 안내 표시] G --> H[실시간 진행 상황] I[제조 목록 업로드] --> F J[4개 웹캠 병렬 처리] --> A K[PyQt5 GUI] --> H
주요 기술적 도전과 해결책
1. 제조 환경 변화에 robust한 객체 탐지
도전과제
- 초기 성능: 객체 탐지 정확도 0.65 (mAP@0.5 기준)
- 환경 변수: 조명 변화, 재료 적재 상태, 제조 환경에 따른 탐지 성능 저하
- 데이터 제약: 제한된 학습 데이터로 다양한 환경 조건 학습 어려움
문제 해결 과정
1단계: 실제 제조 환경 데이터 수집
# 데이터 수집 전략
data_collection_strategy = {
"영상 수": 50개,
"프레임 추출": "약 400장 BBox 라벨링",
"환경 조건": [
"아침/점심/저녁 조명 변화",
"재료 적재 상태 변화",
"제조 카운터 위치별 각도",
"용기 종류별 (빈 용기 ~ 완성품)"
]
}
2단계: 제조진 협업 기반 라벨링 품질 향상
- 도메인 전문가 검수: 제조 담당자와 협업으로 정확한 객체 구분
- 프레임별 세밀한 분석: 영상을 프레임 단위로 분할하여 상황별 라벨링
- 품질 검증: 제조진 직접 검수로 라벨링 정확도 확보
3단계: YOLOv5s 모델 최적화
# YOLOv5s 학습 설정
training_config = {
"model": "YOLOv5s", # 실시간 처리를 위한 경량 모델
"epochs": 300,
"batch_size": 16,
"img_size": 640,
"data": "container_dataset.yaml",
"weights": "yolov5s.pt" # 사전 학습된 가중치
}
# 데이터셋 구성
dataset_structure = {
"train": "400장 (80%)",
"val": "100장 (20%)",
"classes": ["empty_container", "filled_container", "completed_product"]
}
성과
- 정확도 향상: 0.65 → 0.8+ 달성 (mAP@0.5 기준, 23% 이상 개선)
- 환경 적응성: 다양한 조명 및 재료 상태에서 안정적 탐지
- 실시간 성능: <1초 지연으로 제조 속도에 맞춘 처리
2. 실시간 객체 추적 및 방향성 카운팅
도전과제
- 움직이는 객체 추적: 제조 카운터에서 이동하는 용기의 정확한 추적
- 역방향 오카운팅 방지: 용기가 역방향으로 움직일 때 잘못된 카운팅 방지
- 실시간 성능: 초기 1초 딜레이 문제로 제조 속도 저해
문제 해결 과정
1단계: YOLOv5s + DeepSORT 통합 시스템
2단계: 추적 ID 관리 시스템
# OCP, 객체 중앙점 설정
def box_label(self, box, label='', color=(128, 128, 128), txt_color=(255, 255, 255)):
# Add one xyxy box to image with label
if self.pil or not is_ascii(label):
self.draw.rectangle(box, width=self.lw, outline=color) # box
if label:
w, h = self.font.getsize(label) # text width, height
outside = box[1] - h >= 0 # label fits outside box
self.draw.rectangle(
(box[0], box[1] - h if outside else box[1], box[0] + w + 1,
box[1] + 1 if outside else box[1] + h + 1),
fill=color,
)
# self.draw.text((box[0], box[1]), label, fill=txt_color, font=self.font, anchor='ls') # for PIL>8.0
self.draw.text((box[0], box[1] - h if outside else box[1]), label, fill=txt_color, font=self.font)
else: # cv2
p1, p2 = (int(box[0]), int(box[1])), (int(box[2]), int(box[3]))
center_coordinates = (int(box[0] + (box[2]-box[0])/2), int(box[1] + (box[3] - box[1])/2))
cv2.rectangle(self.im, p1, p2, color, thickness=self.lw, lineType=cv2.LINE_AA)
cv2.circle(self.im, center_coordinates, radius=3, color=color, thickness=3)
if label:
tf = max(self.lw - 1, 1) # font thickness
w, h = cv2.getTextSize(label, 0, fontScale=self.lw / 3, thickness=tf)[0] # text width, height
outside = p1[1] - h >= 3
p2 = p1[0] + w, p1[1] - h - 3 if outside else p1[1] + h + 3
cv2.rectangle(self.im, p1, p2, color, -1, cv2.LINE_AA) # filled
cv2.putText(self.im,
label, (p1[0], p1[1] - 2 if outside else p1[1] + h + 2),
0,
self.lw / 3,
txt_color,
thickness=tf,
lineType=cv2.LINE_AA
#개수판단
class Count:
def count_1_function(det, im, s, im0, names, outputs, tracker_list, dt, i, t3,t2,tracking_method,annotator, save_txt, txt_path,frame_idx, save_vid, save_crop, show_vid, hide_labels, hide_conf, hide_class, path, imc, save_dir, p):
w, h = im0.shape[1], im0.shape[0]
if det is not None and len(det):
det[:, :4] = scale_coords(im.shape[2:], det[:, :4], im0.shape).round()
for c in det[:, -1].unique():
n = (det[:, -1] == c).sum() # detections per class
s += f"{n} {names[int(c)]}{'s' * (n > 1)}, "
t4 = time_sync()
outputs[i] = tracker_list[i].update(det.cpu(), im0)
t5 = time_sync()
dt[3] += t5 - t4
if len(outputs[i]) > 0:
for j, (output, conf) in enumerate(zip(outputs[i], det[:, 4])):
bboxes = output[0:4]
id = output[4]
cls = output[5]
global count_web_1, data_web_1, order_index_web_1, step_count_web_1
center_coordinates = (
int(bboxes[0] + (bboxes[2]-bboxes[0])/2), int(bboxes[1] + (bboxes[3] - bboxes[1])/2))
if (int(bboxes[0]+(bboxes[2] - bboxes[0])/2) < (int(w/2))) and (id not in data_web_1):
# like sensor
im0 = cv2.rectangle(im0, (0,0), (w,h), (0,0,255), -1)
count_web_1 += 1
data_web_1.append(id)
order_data_count = order_data['Count']
step_count_web_1 += 1
if step_count_web_1 >= int(order_data_count[order_index_web_1]):
order_index_web_1+= 1
step_count_web_1 = 0
common_save_functions(output, save_txt, txt_path, frame_idx, i, save_vid, save_crop, show_vid, id, cls,hide_labels, names, hide_conf, conf, hide_class, annotator, bboxes, path, imc, save_dir, p)
# LOGGER.info(f'{s}Done. yolo:({t3 - t2:.3f}s), {tracking_method}:({t5 - t4:.3f}s)')
else:
# strongsort_list[i].increment_ages()
# LOGGER.info('No detections')
pass
im0 = annotator.result()
return im0, count_web_1, order_index_web_1, step_count_web_1
3단계: 성능 최적화
- 경량화 모델: YOLOv5s 선택으로 추론 속도 향상
- 효율적 추적: DeepSORT 파라미터 튜닝으로 ID 스위칭 최소화
- 멀티스레딩: 각 웹캠별 독립 처리로 병렬 성능 확보
성과
- 정확한 카운팅: 좌→우 단방향 카운팅으로 역방향 오류 방지
- 실시간 처리: 1초 딜레이 해결로 제조 속도에 맞춘 시스템
- 안정적 추적: 객체 ID 관리로 중복 카운팅 방지
3. 로컬 환경 대응 독립 실행 시스템
도전과제
- 네트워크 제약: 제조 현장에서 웹 기반 시스템 사용 불가
- 외부 의존성: 클라우드 서비스나 외부 API 연결 불가능
- 배포 복잡성: 별도 서버 설치나 복잡한 환경 설정 어려움
문제 해결 과정
1단계: PyQt5 네이티브 애플리케이션 개발
2단계: Pyinstaller 기반 .exe 패키징
3단계: 로컬 완전 독립 처리
- 모든 연산 로컬 처리: AI 모델 추론부터 결과 표시까지 완전 오프라인
- 설정 파일 로컬 저장: 제조 목록 및 옵션 설정을 로컬 파일로 관리
- 결과 데이터 로컬 저장: 처리 결과 및 로그를 로컬 폴더에 저장
성과
- 완전 독립 실행: 네트워크 연결 없이 모든 기능 작동
- 간편 배포: .exe 파일 하나로 설치 및 실행 완료
- 로컬 사용: 외부 연결 없이 로컬 환경에서 안전한 사용
4. 직관적 제조 진행 상황 시각화
도전과제
- 복잡한 옵션 관리: 다양한 커스터마이징 옵션을 제조진이 쉽게 파악 필요
- 실시간 진행 표시: 현재 제조 상황과 다음 단계를 명확히 안내
- 비개발자 사용성: 제조 담당자가 직관적으로 이해할 수 있는 인터페이스
문제 해결 과정
1단계: 색상 기반 직관적 시각화
2단계: 실시간 카운터 및 진행 상황 표시
3단계: 다중 옵션 동시 표시
- 화면 분할: 여러 옵션을 동시에 표시할 수 있는 유연한 레이아웃
- 우선순위 표시: 현재 진행 중인 옵션을 강조 표시
- 히스토리 표시: 완료된 옵션 목록을 별도 영역에 표시
성과
- 직관적 이해: 색상 기반 표시로 제조진이 즉시 상황 파악 가능
- 실시간 안내: 현재와 다음 단계를 명확히 제시하여 혼란 방지
- 사용자 친화성: 비개발자도 교육 없이 바로 사용 가능한 인터페이스
5. 다중 웹캠 연동 및 성능 최적화
도전과제
- 4단계 제조 라인: 각 제조 단계별 독립 웹캠으로 전체 프로세스 모니터링
- 성능 한계: 다중 스트림 처리 시 하드웨어 리소스 제약
- 동기화: 각 단계별 처리 결과를 실시간으로 통합 관리
문제 해결 과정
1단계: 멀티스레딩 기반 병렬 처리
2단계: 리소스 최적화 및 성능 한계 확인
3단계: 중앙 집중식 결과 통합
성과
- 다중 스트림 지원: 최대 4개 웹캠 동시 처리로 전체 제조 라인 모니터링
- 성능 한계 명확화: 4개 이상 시 성능 저하 발생 확인 및 사용자 안내
- 안정적 운영: GPU/CPU 리소스 효율 분배로 시스템 안정성 확보
성능 평가 및 검증
객체 탐지 성능
실시간 처리 성능
- 지연 시간: <1초 (제조 카운터 속도에 맞춘 실시간 처리)
- 처리 안정성: 연속 8시간 운영 시 오류 없음
- 다중 스트림: 4개 웹캠 동시 처리 시 안정적 성능 유지
비즈니스 임팩트 및 성과
효율성 향상
- 스티커 라벨링 제거: 용기별 개별 라벨 부착 작업 완전 자동화
- 옵션 누락 방지: 하루 100-200개 제조 시 누락 사례 대폭 감소
- 제조 집중도 향상: 수작업 카운팅 부담 제거로 제조 품질에 집중
품질 관리 강화
- 실시간 모니터링: 제조 진행 상황 실시간 추적으로 품질 일관성 확보
- 오류 사전 방지: 잘못된 옵션 진행 시 즉시 알림으로 재작업 방지
기술적 가치 창출
- 실용적 솔루션: 실제 제조 환경의 제약 조건을 모두 고려한 실무 적용 가능 시스템
- 확장 가능성: 다양한 제조 환경에 적용 가능한 모듈화된 아키텍처
기술적 학습 및 성장
Computer Vision 전문성
- 객체 탐지: YOLO 모델 최적화 및 실제 환경 적용 경험
- 객체 추적: DeepSORT 기반 다중 객체 추적 시스템 구현
- 실시간 처리: 제조 환경에서 요구되는 실시간 성능 최적화
- 데이터 수집: 실제 환경에서의 효과적 학습 데이터 구축 방법론
제조 도메인 이해
- 현장 중심 개발: 실제 제조 환경의 변수(조명, 재료 상태)를 충분히 고려한 robust한 모델 개발
- 도메인 협업: 제조 담당자와의 협업을 통한 데이터 품질 향상 및 실용성 확보
- 프로세스 최적화: 기존 제조 워크플로우 분석 및 AI 기술 적용 방안 도출
- 사용자 중심 설계: 비개발자도 직관적으로 사용할 수 있는 인터페이스 설계
시스템 엔지니어링 역량
- 독립 실행 시스템: 네트워크 제약이 있는 환경에서의 완전 독립적 AI 시스템 구축
- 멀티스레딩: 다중 웹캠 병렬 처리를 위한 효율적 스레드 관리
- 리소스 최적화: 제한된 하드웨어 리소스에서 최대 성능 달성을 위한 최적화
- GUI 개발: PyQt5 기반 사용자 친화적 데스크톱 애플리케이션 개발
제약 조건 하에서의 창의적 해결
- 로컬 환경: 외부 연결 불가 환경에서 완전 독립적 시스템 구축
- 실시간 성능: 제조 속도에 맞춘 <1초 지연 달성
- 하드웨어 제약: 제한된 GPU/CPU 리소스에서 4개 웹캠 동시 처리
- 사용성: 복잡한 AI 시스템을 제조진이 쉽게 사용할 수 있도록 단순화
프로젝트 관리 및 협업
도메인 전문가 협업
- 요구사항 분석: 제조진과의 지속적 소통으로 실제 현장 문제 파악
- 데이터 검수: 제조 담당자 직접 참여로 라벨링 품질 향상
- 테스트 협업: 실제 제조 환경에서의 시스템 검증 및 피드백 수집
- 사용성 개선: 현장 사용자 관점에서 인터페이스 지속 개선
기술적 문서화
- 구현 문서: 각 컴포넌트별 기술 사양 및 최적화 내용 상세 기록
- 사용자 매뉴얼: 제조진 대상 시스템 사용법 및 문제 해결 가이드
결론 및 시사점
기술적 가치
- 실무 적용 AI: 실제 제조 환경의 모든 제약 조건을 고려한 실용적 AI 솔루션
- 독립 실행 시스템: 외부 의존성 없이 완전 독립적으로 작동하는 AI 시스템 구축 경험
- 실시간 처리: 제조 현장에서 요구되는 실시간 성능 달성 기술
개발자로서의 성장
- 현장 중심 사고: 기술적 완성도보다 실제 사용자의 문제 해결에 집중
- 제약 조건 극복: 한정된 자원과 환경에서 창의적 해결책 도출 능력
- 도메인 협업: 비개발자와의 효과적 소통 및 협업을 통한 가치 창출
- 실용성 우선: 복잡한 기술보다 실제로 작동하는 솔루션 개발 역량