요약

키오스크는 무인 시스템의 대표 사례이다. 영화관의 키오스크는 무인 기반으로 사용자는 티켓을 구입할 수 있고, 음식점에는 키오스크를 이용하여 음식 주문을 할 수있다. 이와 같이 키오스크는 다양한 자동화 사례에 적용할 수 있다. 하지만 일반적인 사용자가 아닌 외국인, 연세가 많으신 분 들은 키오스크 이용이 매우 어렵다. 따라서 현재 이용하는 사용자의 정보에 맞게 키오스크의 UI를 사용자 적응형으로 개발한다면 더욱 많은 사용자에게 편한 키오스크 사용 경험을 제공할 것이다. 따라서 인접한 사용자의 정보를 받아 키오스크의 UI를 적응형으로 바꾸는 기술은 필요하다.

해당 포스트는 HTTP 통신을 기반으로 Flask framework 서버 프로그램, 키오스크 앱, 사용자 앱을 구분하여 개발한 확장성 있는 통신 시스템을 정리한 포스트이다. 구체적인 구현 코드는 제거하였고 시스템 구현 중 생기는 환경 설정 문제, 사용하면 유용한 함수들을 정리했다. 마지막으로 구현한 통신 시스템의 결과 사진을 공개하고 포스트를 끝마친다.

 

시스템 개발 환경

1. 사용 언어

- python 3.7

AWS IaaS 타입으로 받은 터미널에서 Flask framework 기반으로 서버를 구축하기 위해서 사용했다.

- Kotlin

키오스크, 사용자 앱 개발을 위해 사용했다.

 

2. IDE

- Android studio [DOWN LINK]

- Visual studio code [DOWN LINK]

 

3. IaaS Type Server 

- AWS Lightsail (ubuntu)

AWS EC2 보다 셋팅이 간단하며 무엇보다 3개월 무료로 사용할 수있다. 

 

- Apache

개발한 서버 스크립트를 웹상으로 배포하기 위해 사용하였다. 

설치하는데 도움받은 링크 [LINK]

 

- Flask framework

HTTP 통신을 기반으로 빠르게 구현할 수 있어서 사용하였다.

 

4. Client 사용자 타입

- Android 7.0

기본으로 제공받은 장치의 사양을 따랐다.

5. Client 키오스크 타입

- Android 6.0

기본으로 제공받은 장치의 사양을 따랐다.

 

 

시스템 구상도

구현 핵심 기술 (implementation,  troubleshooting)

1. Flask framework backend 서버 구현

- troubleshooting, implementation link 모음

   1. Flask framework 서버 구현 예제 코드 [LINK]

 

- Flask framework 구현 방법

   2. 구현 방법

    - 데이터 송수신 프로토콜 설계

      키오스크가 접속하는 서버 접속 링크 : http://{SERVERIP}:{PORT}/updatekiosklocation/<kiosk_updateprotocol>

      스마트폰앱이 접속하는 서버 접속 링크 : http://{SERVERIP}:{PORT}/updateuserlocation/<user_updateprotocol>

    - 코드 예시

app = Flask(__name__) 

if __name__ == '__main__':
    #Flask 서버 시작
    app.run(host='0.0.0.0',port=5000)


#스마트폰 유저로 부터 요청을 받았을 경우
@app.route('/updateuserlocation/<user_updateprotocol>')
def Updateuserlocation(user_updateprotocol):
    userdatas = user_updateprotocol.split(',')

    ...
    
    return user_updateprotocol

#키오스크로 부터 요청을 받았을 경우
@app.route('/updatekiosklocation/<kiosk_updateprotocol>')
def Updatekiosklocation(kiosk_updateprotocol):

    kioskdatas = kiosk_updateprotocol.split(',')
    
    ...
    
    return GetNearbyUser(kioskdatas)

2. Android 기기의 GPS 위치 정보 획득 API 사용 

- troubleshooting, implementation link 모음

   1. GPS 위치 정보 획득 [LINK, LINK]

   2. 키오스크에 앱 배포를 위해 빌드하기

       - 상단 툴바에 Generate Signed Bundel / APK 버튼 클릭!

       - APK 체크!

     - 빈칸 채워넣기!

    - release 체크 하고 Finish!

     - 화면 우측하단에 Generate Signed APK 팝업이 뜨면 완료!

     

      - 그다음은 해당 .apk 파일을 구글드라이브를 이용하든 사용하고자 하는 장치에서 다운로드하면 자동으로 설치가 됨!

3. Client와 Server 간의 HTTP 통신 기술 

- troubleshooting, implementation link 모음

   1. HttpURLConnection class와,Thread 를 이용한 HTTP 통신 구현 [LINK]

   2. https 로만 접근 가능했던 문제 해결 방법 [LINK]

- HTTP url 기반 데이터 전송 예시 코드

var urlText = "http://${SERVER_IP}:${SERVER_PORT}/updateuserlocation/${user_info}"
var url = URL(urlText)

//HTTP 연결 시도 + user_info 데이터 전송!
val urlConnection = url.openConnection() as HttpURLConnection

//HTTP 했는가?
if (urlConnection.responseCode == HttpURLConnection.HTTP_OK) {

	//HTTP 연결 성공!
	Log.d(TAG, "Connect OK")
    
    //서버로 부터 회신된 데이터 확인!
	val streamReader = InputStreamReader(urlConnection.inputStream)
    
    //데이터 읽기용 버퍼 생성
	var buffered = BufferedReader(streamReader)

	val content = StringBuilder()
	while (true) {
		val line = buffered.readLine() ?: break
		content.append(line)
	}
	
    //content : 서버로 부터 응답 받은 데이터를 가짐
    
    //데이터 읽기용 버퍼 닫기
	buffered.close()
    
    //연결 종료
	urlConnection.disconnect()
}

 

테스트 사진

통신 시험용 사용자 앱 화면
통신 시험용 키오스크 앱 화면
서버 터미널 화면

'M.S > Toy project' 카테고리의 다른 글

자동 출석 체크 시스템 개발  (2) 2021.04.30

배경

COVID 19 사태 이후 온라인 강의가 증가하고 있다. 오프라인에서 온라인 강의로 전향되면서 대학교 강의 1개에 수강할 수 있는 수강생 인원이 크게 증가하였다. COVID 19 사태 전까지만 해도 일반 전공 수업을 1개의 강의에 20~40명 정도였다. 하지만 온라인 강의가 가능한 지금은 수용 가능한 수강생 최대 인원이 100명으로 증가하고 이런 영향으로 조교 업무를 맡은 나에게는 현재 92명을 일주일에 2번 출석체크해야 하는 상황이다. 이는 대학원생인 나에게 시간 낭비를 시키는 영향을 준다. 그래서 현재 인원의 상태를 스크린 숏으로 이미지를 저장 후 나머지 출결 정보는 컴퓨터에게 맡기는 프로그램을 개발하기로 했다. 심플할수록 좋다. 기능은 OCR, 학번 별 오름차순 정렬, 결과 출력이다.

요구 사항

1. 현재 강의를 듣고 있는 수강생들의 ID(학번 이름)을 엑셀 파일에 학번별 오름차 순으로 정렬하여 저장.
2. 인원이 많을 경우 수강들의 ID(학번 이름)을 저장하고 있는 사진들을 한 폴더에 저장 후 프로그램 실행하여 해당 경로를 입력 시 해당 경로의 사진의 글자를 인식하여 N번 기능을 수행.
3. 출석체크 결과는 python shall에 엑셀로 복사 붙여 넣기 하기 쉽게 출력

필요 기능

1. OCR
2. excel 파일 읽기
3. 출석부 명단 데이터 정리

개발 환경

IDLE : Anaconda, Spyder
API : OpenCV, tesseract, pandas, numpy
Language : Python 3.7 이상

예상 개발 기간

7일

테스트 방법

실제 사진과 결과 비교

구현

사용 라이브러리

import cv2 import os try: from PIL import Image except ImportError: import Image import pytesseract import numpy as np import pandas as pd

유틸 함수 1

설명 : 지정 경로 폴더 안에 있는 모든 이미지 경로 가져오기
Paramter
- folderPath : 지정할 폴더의 절대 경로

def getFileList(folderPath): fileList = os.listdir(folderPath) answerFileList = [] for fileName in fileList: answerFileList.append(folderPath + '\\' + fileName) return answerFileList

영상 처리 함수

설명 : 지정한 경로의 이미지를 열고 이미지 전처리 후 pytesseract를 이용한 ocr 결과 가져오기
Parameter
- loadImagePath : 불러올 이미지의 절대 경로
- savePath : 이미지 전처리 후 이미지를 저장할 절대 경로

def GetNameList(loadImagePath, savePath): # 설치한 tesseract 프로그램 경로 (64비트) pytesseract.pytesseract.tesseract_cmd = r'C:\Program Files\Tesseract-OCR\tesseract' image = cv2.imread(loadImagePath) #bgr to gray gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY) #이미지 크기 조절 gray = cv2.resize(gray, dsize=(0, 0), fx=1.5, fy=1.5, interpolation=cv2.INTER_LINEAR) #컨볼루션 sharpening = np.array([[-1, -1, -1, -1, -1], [-1, 2, 2, 2, -1], [-1, 2, 9, 2, -1], [-1, 2, 2, 2, -1], [-1, -1, -1, -1, -1]]) / 9.0 gray = cv2.filter2D(gray, -1, sharpening) # write the grayscale image to disk as a temporary file so we can # 글자 프로세싱을 위해 Gray 이미지 임시파일 형태로 저장. #filename = '{}.bmp'.format(os.getpid()) filename = savePath cv2.imwrite(filename, gray) # Simple image to string text = pytesseract.image_to_string(Image.open(filename), lang='kor') #1차 필터링 : 줄 단위 save = text.split('\n') #2차 필터링 : 글자수 6개 이상 #3차 필터링 : 글자에 숫자가 7개이상 firstfilter = [] for name in save: if len(name) >= 6 and len(name) <= 15: digitCount = 0 for checkDigit in name: if checkDigit.isdigit(): digitCount += 1 if digitCount >= 7: firstfilter.append(name) return firstfilter

사용 함수 1

설명 : 지정한 폴더 경로에 접근하여 영상 처리 함수를 사용 후 결과 명단 가져오기
Parameter
- folderPath : 체크할 이미지들이 들어있는 폴더 경로
(절대 경로 (ex. C:\Projects\MS\attendanceCheck))

def GetAllNameList(folderPath): fileList = getFileList(folderPath) AllNameList = [] for filePath in fileList: file_name, file_ext = os.path.splitext(filePath) savefilelist = list(file_name) savefilelist.insert((len(savefilelist)), '_.bmp') saveAfterProcessImagePath = ''.join(savefilelist) temp = GetNameList(filePath, saveAfterProcessImagePath) for name in temp: AllNameList.append(name) #모든 이름 내림차순 정렬 AllNameList.sort() return AllNameList

사용 함수 2

설명 : 지정한 엑셀 파일 경로에 접근하여 출석 명단을 가져온다.
Parameter
- excelPath : 출석 명단 원본 경로
(절대 경로 (ex. C:\Projects\MS\attendanceCheck\check.xlsc))

def UpdateCheckList(excelPath): df = pd.read_excel(excelPath) result = [] for index in range(len(df['number'])): temp = [] temp.append(str(df['number'][index])) temp.append(df['name'][index]) temp.append(False) result.append(temp) return result

사용 함수 3

설명 : 지정한 엑셀 파일 경로에 접근하여 출석 명단을 가져온 후 이전 전처리 과정에서 찾은 명단과 비교하는 함수
Parameter
- excelPath : 출석 명단 원본 경로
(절대 경로 (ex. C:\Projects\MS\attendanceCheck\check.xlsc))
- nameList : 영상처리로 찾아낸 명단 리스트
- result : '사용 함수 2' 과정에서 가져온 명단 리스트

def GetResult(excelPath, nameList, result): df = pd.read_excel(excelPath) for index in range(len(df['number'])): for checkAttendance in nameList: if checkAttendance.find(str(df['number'][index])) >= 0 or checkAttendance.find(str(df['name'][index])) >= 0: result[index][2] |= True break else: result[index][2] |= False return result

데이터 추출 명령어

설명 : 4번의 검사를 수행한다. 1번 수행할 때마다 이미지를 리사이징 해서 체크한다. 정확도가 올라가는 효과를 기대할 수 있다.

exelPath = "엑셀 파일 경로" imagePath = "폴더 경로" result = UpdateCheckList(exelPath) #총 4번 다시 체크 이미지 사이즈 조절 하면서 체크 많이 할수록 정확도가 올라감 for i in range(4): arr = GetAllNameList(imagePath) result = GetResult(exelPath, arr, result)


출력 결과


학번, 이름, 출석 결과로 출력함.
, 로 구분 짓기 때문에 엑셀로 복붙 하면 끝!
자 그럼 이제 출석체크 업무는

1. 강의 참가자 명단 스크린 샷 찍기

참가자 명단 스샷


2. 테스트할 폴더에 넣기

참가자 명단 사진들


3. 프로그램 돌리기
4. 결과 복사 붙여 넣기
5. 혹시나 x 표 실시간 줌에서 검색해서 찾기


참고 사이트
ansan-survivor.tistory.com/313

[Python OpenCV] 파이썬 글자 인식, 파이썬 OCR, 파이썬 Tesseract 사용

파이썬을 이용해서 글자를 인식하는 프로그램이다. 아래 블로거님을 참고해서 제작 했다. (참고 링크) junyoung-jamong.github.io/computer/vision,/ocr/2019/01/30/Python%EC%97%90%EC%84%9C-Tesseract%EB%A5%BC-..

ansan-survivor.tistory.com

'M.S > Toy project' 카테고리의 다른 글

위치 기반 사용자 적응형 키오스크 프로젝트  (0) 2022.08.20

+ Recent posts