WI:SH Kiosk

WI:SH Kiosk

Write It: Scan & Handle — 키오스크 접근성 개선 프로젝트

종이에 쓴 숫자를 스캔, 인식해 주문을 넣는 키오스크입니다. 스캐너(WIA), QR 코드(ZXing · QRCoder), ONNX 런타임(모델은 PyTorch로 학습)으로 노년층도 쉽게 주문할 수 있도록 설계했습니다.

핵심 목표

  • 손글씨 기반 주문 입력과 접근성 강화
  • 스캔 → 인식 → 처리 전체 흐름 자동화
  • 현장 배치에 필요한 운영 구성 제공

저장소 구조 하이라이트

  • KioskAI — 프린트 · 스캔 · 인식
  • wishKioskDID/DIDReceive — DID System
  • trainModel.py — 모델 학습 스크립트
  • copy_these_files — 실행 전 복사 파일

주요 기능

  • 스캐너(EPSON ES-50)로 입력된 용지 자동 감지 및 전처리
  • ZXing으로 QR 코드 인식, QRCoder로 QR 생성
  • ONNX 런타임 기반 손글씨 분류/인식 (PyTorch 학습)
  • DID 시스템 보조 모듈 연동

동작 흐름

  1. 사용자 필기 → 스캔 이미지 획득
  2. 이미지 전처리 → QR 코드 인식
  3. ONNX 모델로 숫자 판별
  4. 주문 처리 및 DID 연동

설치 및 준비

사전 요구사항

  • Windows 10/11, Visual Studio 2022 (or .NET 8.0)
  • .NET SDK 타깃: net8.0-windows
  • WIA 호환 스캐너 (EPSON ES-50 스캐너)
  • 프린터 (PeriPage P40 프린터)

다운로드

Git 사용 또는 ZIP 다운로드

git clone https://github.com/Team-ToyoTech/WISH-Kiosk.git
cd WISH-Kiosk

Visual Studio에서 열기

  1. wishKiosk.sln 열기 → NuGet 복원
  2. 솔루션 빌드 (Ctrl+Shift+B)

실행 전 파일 복사

저장소 copy_these_files 내용을 실행 폴더로 복사

  • onnx_model 폴더 → KioskAI\bin\Debug\net8.0-windows\ 로 복사
  • sound.wav 파일 (주문 알림 소리) → wishKioskDIDReceive\bin\Debug\net8.0-windows\ 로 복사

사용 방법

  1. KioskAI, wishKioskDIDReceive 실행
  2. 스캐너가 WIA로 정상 인식되는지 확인
  3. 스캔 → 인식 결과 확인
  1. 스캔 버튼 → 문서 스캔
  2. 바코드/QR 감지 → 주문 식별
  3. 모델 추론 → 숫자 인식
  4. 주문 처리 → DID 수신/알림
  • 스캐너 인식 실패: WIA 드라이버/USB 포트 확인
  • 패키지 오류: NuGet 복원/재설치
  • 모델 로드 실패: onnx_model 경로 재확인

AI 모델

  • handWritingPreprocess.py : 직접 작성한 이미지에 대해 ±0.5°부터 ±5.0°까지 0.5° 간격으로 회전본 생성
  • invert.py : MNIST 데이터셋의 이미지 색상 반전
  • make.py : MNIST 데이터셋의 투명 처리된 숫자 이미지를 기본 배경 위에 [2.0, 2.5, 3.0] 배로 확대 후 중앙, 랜덤 위치에 합성
  • makeNaN.py : 이미지 테두리에 랜덤 짧은 선을 1 - 3개 그려 다양한 노이즈(NaN) 샘플 생성
  • SelectImg.py : 폴더 내 이미지 일정 비율을 무작위 추출, 복사
  • copyFile.py : 지정 파일을 번호 증가 형태({startIndex}.{ext})로 N개 복제
  • randName.py : 폴더 내 파일 이름을 충돌 없이 6자리 랜덤 번호로 일괄 변경
GitHub 저장소
  1. 이미지를 64 × 64 로 조정 (학습 효과 극대화 위해 이미지 해상도 낮춤)
  2. PyTorch 이용한 모델 학습
  3. ONNX로 모델 내보내기
trainModel.py 코드

시연

스크린샷

fasd

WI:SH Server

WI:SH Server

WI:SH Kiosk와 연동되는 서버 구성입니다. 주문 접수/상태 관리, 외부 결제 연동, 큐 표출 등 백엔드 역할을 담당합니다. (Toss Payments 기반 결제)

서버 주요 기능

  • 키오스크 ↔ 서버 주문/결제 플로우
  • 주문 대기/완료 큐 관리 및 조회
  • Toss Payments 결제 승인/브랜드페이/빌링 샘플 엔드포인트
결제 키는 실제 상용/테스트 키로 교체해야 합니다.

연동 개요

  1. 키오스크 → /pay 로 결제 세션 생성
  2. 브라우저(또는 WebView)에서 결제 → 서버에서 승인 처리
  3. 결제 완료 시 주문 등록(/order/add/:id 또는 카운터 결제 플로우)

서버 설치 및 실행

다운로드

git clone https://github.com/Team-ToyoTech/WISH-Server.git
cd WISH-Server
npm install express body-parser
node Server.js

기본 포트 4000으로 기동됩니다.

API 사용 방법

기본 URL: http://localhost:4000

AWS 서버 URL: https://wish.toyotech.dev

:id: 랜덤으로 발급 받은 결제 번호

orderN: 주문 번호

결제 플로우

POST /pay — 결제 세션 생성
req  : { "amount": 12000 }
resp : { "redirectId": "<paymentId>" }
GET /checkout/:id — 결제창 페이지 (내부용)

브라우저에서 Toss 결제 위젯 로드 후 성공/실패로 리다이렉트.

GET /ispaying/:id — 결제 상태 폴링
resp : { "status": "pending" | "paid" | "failed" }
POST /order/add/:id — 결제완료 주문 등록
req  : [ { "Name": "라면", "Count": 2 }, ... ]
resp : { "orderNumber": 123 }
POST /pay/counter — 카운터 결제(선주문) 생성
req  : { "amount": 10000, "orders": [ { "Name":"라면","Count":2 } ] }
resp : { "orderNumber": 101, "orderId": "XXXXX" }
GET /pay/complete/:orderN — 카운터 결제 완료 처리
resp : { "status": "success" | "fail" }

주문 큐 / DID

GET /order/get — 대기 중 주문 목록 GET /order/getid — 대기 중 주문 번호 목록 GET /order/complete/set/:orderN — 준비완료 처리 GET /order/complete/get — 완료된 주문 목록 GET /order/complete/getid — 완료된 주문 번호 목록 GET /order/complete/cancel/:orderN — 완료 취소 DELETE /order/del/:orderN — 수령 처리(완료 목록에서 제거)

cURL 예시

# 세션 생성 → redirectId 확인
curl -X POST http://localhost:4000/pay \
  -H "Content-Type: application/json" \
  -d '{ "amount": 12000 }'

# 결제 상태 폴링
curl http://localhost:4000/ispaying/<redirectId>

# 결제완료 후 주문 등록
curl -X POST http://localhost:4000/order/add/<redirectId> \
  -H "Content-Type: application/json" \
  -d '[{ "Name": "라면", "Count": 2 }]'

서버 사용 팁

  1. 로컬에서 서버 기동 후 http://localhost:4000 확인
  2. 키오스크 클라이언트에 서버 URL 설정
  1. 키오스크: /pay → 웹 결제
  2. 서버: 승인 처리
  3. 키오스크: /order/add/:id 등록
  • 포트 충돌 → 포트 변경/점유 해제
  • 키 교체 누락 → Toss 키 값 점검
  • 프록시/방화벽 → 로컬 접근 허용