목표 시스템

  1. 티처블 머신 - 가위바위보 추론 모델 생성, 다운로드

  2. 파이썬 프로그래밍

가. 웹캠으로 손모양 인식

나. 인공지능 추론모델로 가위바위보 추론

다. 추론 결과에 따라 컴퓨터 비프음 발생

  • kai >> 비프 1회
  • bai >> 비프 2회
  • bo >> 비프 3회
  • none >> 비프 4회


개발 환경 구축

가상 환경 만들기

conda create -n tf tensorflow

conda activate tf

Visual Studio Code 설치

Visual Studio Code란?

  • 마이크로소프트가 개발한 소스 코드 편집기로서 Windows, 리눅스, MacOS 등에서 사용할 수 있다.

  • MIT 라이센스로 오픈소스로 공개되어 있으며, 무료로 사용할 수 있다.

  • 전세계 개발자들이 가장 애용하는 에디터이다.

Visual Studio Code 설치하기

Visual Studio Code 시작하기

  • C:에 pywork 폴더 만들기

  • VSC에서 파일>폴더 열기>C:\pywork 선택

  • 새파일 만들기(Ctrl+n) 'test.py'

  • 편집창에서 print('hello')

  • 왼쪽 아래 인터프리터를 눌러 Python 3.8.10-64bit('tf':conda)선택

  • 실행버튼을 누르거나 Ctrl+F5를 눌러서 실행하고 결과를 확인

Open CV 설치

Open CV란?

  • Open Source Computer Vision Library

  • Open CV는 실시간 컴퓨터 비전을 목적으로 한 프로그래밍 라이브러리이다.

    • 영상 처리, 컴퓨터 비전, 기계 합습과 관려된 전통적인 알고리즘

    • 얼굴 검출과 인식, 객체 인식, 객체 3D 모델 추출, 스테레오 카메라에서 3D 좌표 생성

    • 고해상도 영상 생성을 위한 이미지 스티칭, 영상 검색, 적목 현상 제거, 안구 운동추적

  • 처음에는 인텔이 개발하였다.

  • 실시간 이미지 프로세싱에 중점을 둔 라이브러리이다.

  • 오픈소스 BSD허가서 하에서 무료 사용 가능하다.

Open CV 설치하기

  • VSC 터미널 창에서 현재 가상환경이 (tf)인지 확인하고 실행

  • 파이썬 패키지 관리기를 최신버전으로 업그레이드

python -m pip install --upgrade pip

  • Open CV 기본 모듈 설치

pip install opencv-python

  • Open CV 추가 모듈 설치

pip install opencv-contrib-python

  • Open CV 설치 확인

pip show opencv-python

웹캠 이미지 추론하기

실습1: 웹캠 영상 이미지 보기

실습코드 1_cam_view.py

# 웹캠 보기

import cv2 # OpenCV 모듈


cap = cv2.VideoCapture(0, cv2.CAP_DSHOW) # 0번 카메라 시작


while True:

ret, frame = cap.read() # 프레임 단위로 캡쳐

cv2.imshow('frame', frame) # 캡쳐한 프레임 보기

if cv2.waitKey(25) > 0: break # 아무 키나 눌러서 종료

cap.release() # 웹캠 종료

cv2.destroyAllWindows() # 뷰어 창 닫기


실습1 결과

  • 웹캠의 영상을 프레임 단위로 캡처하여 윈도우 창으로 보여준다.

  • 아무 키나 누르면 프로그램이 종료된다.

실습2: 웹캠 영상 이미지 캡처하기

실습코드 2_cam_capture.py

# 웹캠 캡쳐하기

import cv2 # Open CV 라이브러리


cap = cv2.VideoCapture(0, cv2.CAP_DSHOW) # 0번 카메라 시작

if not cap.isOpened(): # 카메라 동작 확인

print("Could not open webcam")

exit()


while True:

ret, frame = cap.read() # 프레임 단위로 캡쳐

cv2.imshow('quit(q), capture(c)', frame) # 캡쳐한 프레임 보기

# 키보드 입력 읽고 처리. c:캡쳐, q:종료

key = cv2.waitKey(25) & 0xFF

if key == ord('c'):

cv2.imwrite('./images/cap.jpg',frame) # 한글 폴더는 안됨

print(frame.shape, 'cap.jpg is saved')


elif key == ord('q'):

break


cap.release() # 웹캠 종료

cv2.destroyAllWindows() # 뷰어 창 닫기


실습3 결과

실습2 결과

  • 키보드 'c'를 눌러 카메라의 프레임을 캡처한다.

images폴더 아래에 'cap.jpg' 파일로 저장된다.

  • 터미널창에는 캡처된 이미지의 shape 정보가 표시된다.

예] (480, 640, 3) image is saved

실습3: 관심 영역 설정

실습코드 3_cv2_roi.py

# 관심영역(224x224) 설정, 복사

import cv2 # open CV 라이브러리

import numpy as np # 넘파이 라이브러리


# 0번 카메라 시작

cap = cv2.VideoCapture(0, cv2.CAP_DSHOW)

if not cap.isOpened():

print("Could not open webcam")

exit()


# 프레임 캡쳐: 웹캠 해상도(width, height) 확인용

ret, frame = cap.read()

if not ret:

print('Camera is not working!')

exit()


# roi(관심영역) 설정

w = 224; h=224

x = int(frame.shape[1]/2-w/2) # 관심영역 x 시작점

y = int(frame.shape[0]/2-h/2) # 관심영역 y 시작점


while cap.isOpened():

# 프레임 단위로 캡쳐

ret, frame = cap.read()


# roi 영역 복사

roi = frame[y:y+h, x:x+w].copy() # 모델에 제공할 이미지

cv2.rectangle(frame, (x,y), (x+h, y+w), (0,255,0)) # 프레임에 사각형 그리기


# 관심영역 사각형을 표시한 프레임 보기

cv2.imshow('quit(q), capture(c)', frame)


# 키보드 입력 읽고 처리. c:캡쳐, q:종료

key = cv2.waitKey(25) & 0xFF

if key == ord('c'):

cv2.imwrite('./images/cap_img.jpg',frame)

cv2.imwrite('./images/cap_roi.jpg',roi)

print(frame.shape, 'cap_img.jpg image is saved')

print(roi.shape, 'cap_roi.jpg image is saved')


elif key == ord('q'):

break


# 카메라 종료, 뷰어 창 닫기

cap.release()

cv2.destroyAllWindows()


cap_img.jpg

cap_roi.jpg

실습3 결과

  • 키보드 'c'를 눌러 카메라의 프레임을 캡처한다.

images폴더 아래에 cap_img.jpg, cap_roi.jpg 파일이 저장된다.

  • 터미널창에는 캡처된 이미지의 shape 정보가 표시된다.

예] (480, 640, 3) cap_img.jpg image is saved

(224, 224, 3) cap_roi.jpg image is saved

실습4: 캡처 이미지로 추론하기

개발 환경 설정

pillow 라이브러리 설치

  • VSC 터미널 창에서 현재 가상환경이 (aiot)인지 확인하고 실행

  • pillow 설치

pip install pillow

  • pillow 설치 확인

pip show pillow

tensorflow 설치



  • 가상환경 만들 때 tensorflow가 이미 설치됨

실습코드 4_cv2_inference.py

# 캡쳐한 이미지로 추론 실행

import cv2 # open CV 라이브러리 가져오기

import numpy as np # 넘파이 라이브러리 가져오기

import tensorflow.keras # 케라스 라이브러리 가져오기

from PIL import Image, ImageOps # pillow 라이브러리 가져오기


# numpy 소수 출력 설정(명확성을 위해 과학적 표기법 1.e-3 비활성화)

np.set_printoptions(suppress=True)


# 모델 가져오기

print('AI model loading...')

model = tensorflow.keras.models.load_model('./models/keras_model.h5')


# 레이블 가져오기

fp = open('./models/labels.txt', 'r')

lines = fp.readlines()

label = []

for itr in lines:

label.append(itr.split())

fp.close()


# keras 모델에 제공할 형태로 배열을 만듭니다.

# 배열에 넣을 수 있는 '길이'또는 '이미지 수'는 shape 튜플의 첫 번째 값에 의해 결정됩니다.

# 이 경우 1입니다.

data = np.ndarray(shape=(1, 224, 224, 3), dtype=np.float32)


# 0번 카메라 시작

cap = cv2.VideoCapture(0, cv2.CAP_DSHOW)

if not cap.isOpened():

print("Could not open webcam")

exit()


# 프레임 캡쳐: 웹캠 해상도(width, height) 확인용

ret, frame = cap.read()

if not ret:

print('Camera is not working!')

exit()


# roi(관심영역) 설정

w = 224; h=224

x = int(frame.shape[1]/2-w/2) # 관심영역 x 시작점

y = int(frame.shape[0]/2-h/2) # 관심영역 y 시작점


while cap.isOpened():

# 프레임 단위로 캡쳐

ret, frame = cap.read()


# roi 영역 복사

image = cv2.flip(frame,1) # 1은 좌우 반전, 0은 상하 반전

roi = image[y:y+h, x:x+w].copy() # 모델에 제공할 이미지

cv2.rectangle(image, (x,y), (x+h, y+w), (0,255,0)) # 프레임에 사각형 그리기


# 관심영역 사각형을 표시한 프레임 보기

cv2.imshow('quit(q), capture(c)', image)


# 키보드 입력 읽고 처리. c:캡쳐 및 추론, q:종료

key = cv2.waitKey(25) & 0xFF

if key == ord('c'):

# 이미지를 numpy 배열로 변환

image_array = np.asarray(image)


# 이미지 정규화

normalized_image_array = (roi.astype(np.float32) / 127.0) - 1


# 정규화된 이미지를 배열에 넣게

data[0] = normalized_image_array


# 추론 실행

prediction = model.predict(data)

print(prediction)

# 문자로 표시

idx = np.argmax(prediction) # 최댓값의 index 반환

print(idx,': ', label[idx][1])

# 이미지 추론 끝 ================================


elif key == ord('q'):

break


# 자원반환, 화면 종료

cap.release()

cv2.destroyAllWindows()


캡처 및 추론 실행

터미널 창

실습4 결과

  • 키보드 'c'를 눌러 프레임 캡처 및 추론 실행

  • 터미널창에 추론 결과가 표시된다.

예] [[0.9999783 0.0000196 0.00000165 0.00000042]] 0 : kai
해석] 99.997...%의 확률로 '가위'이다.

실습5: 추론 실행 결과로 HW 제어하기

실습코드 5_cv2_hw_control.py

# 캡쳐한 이미지로 추론 실행, HW 제어

import cv2 # open CV 라이브러리 가져오기

import numpy as np # 넘파이 라이브러리 가져오기

import tensorflow.keras # 케라스 라이브러리 가져오기

from PIL import Image, ImageOps # pillow 라이브러리 가져오기

import winsound # 윈도우 소리 모듈


# numpy 소수 출력 설정(명확성을 위해 과학적 표기법 1.e-3 비활성화)

np.set_printoptions(suppress=True)


# 모델 가져오기

print('AI model loading...')

model = tensorflow.keras.models.load_model('./models/keras_model.h5')


# 레이블 가져오기

fp = open('./models/labels.txt', 'r')

lines = fp.readlines()

label = []

for itr in lines:

label.append(itr.split())

fp.close()


# keras 모델에 제공할 형태로 배열을 만듭니다.

# 배열에 넣을 수 있는 '길이'또는 '이미지 수'는 shape 튜플의 첫 번째 값에 의해 결정됩니다.

# 이 경우 1입니다.

data = np.ndarray(shape=(1, 224, 224, 3), dtype=np.float32)


# 0번 카메라 시작

cap = cv2.VideoCapture(0, cv2.CAP_DSHOW)

if not cap.isOpened():

print("Could not open webcam")

exit()


# 프레임 캡쳐: 웹캠 해상도(width, height) 확인용

ret, frame = cap.read()

if not ret:

print('Camera is not working!')

exit()


# roi(관심영역) 설정

w = 224; h=224

x = int(frame.shape[1]/2-w/2) # 관심영역 x 시작점

y = int(frame.shape[0]/2-h/2) # 관심영역 y 시작점


print('KaiBaiBo AI starting...')

print('q:quit, c:capture & inference')

while cap.isOpened():

# 프레임 단위로 캡쳐

ret, frame = cap.read()


roi = frame[y:y+h, x:x+w].copy() # 모델에 제공할 이미지

cv2.rectangle(frame, (x,y), (x+h, y+w), (0,255,0)) # 프레임에 사각형 그리기


# Display the resulting frame

cv2.imshow('quit(q), cap & infer(c)', frame)


# 키보드 입력 읽고 처리. c:캡쳐, q:종료

key = cv2.waitKey(25) & 0xFF

if key == ord('c'):

# 이미지 추론 시작 ===============================

# TM2에서와 동일한 전략으로 이미지 크기를 224x224로 조정합니다.

# 이미지 크기를 최소 224x224 으로 조정한 다음 중앙에서 자르기

# size = (224, 224)

# image = ImageOps.fit(roi, size, Image.ANTIALIAS)


# 이미지를 numpy 배열로 변환

image_flip = cv2.flip(roi, 1) # 1은 좌우 반전, 0은 상하 반전

image_array = np.asarray(image_flip)


# 크기 조정 된 이미지 보기

# cv2.imshow('quit(q), capture(c)', image_array)


# 이미지 정규화

normalized_image_array = (roi.astype(np.float32) / 127.0) - 1


# 정규화된 이미지를 배열에 넣게

data[0] = normalized_image_array


# 추론 실행

prediction = model.predict(data)

print(prediction)

# 문자로 표시

idx = np.argmax(prediction) # 최댓값의 index 반환

print(idx,': ', label[idx][1])


# HW 제어

for _ in range(idx+1):

winsound.Beep(1000,250)

# 이미지 추론 끝 ================================


elif key == ord('q'):

break


# When everything done, release the capture

cap.release()

cv2.destroyAllWindows()

print('Bye...')


캡처 및 추론 실행

터미널 창

실습5 결과

  • 키보드 'c'를 눌러 프레임 캡처 및 추론 실행

  • 추론 결과가 터미널 창에 나타나고,

[[0.9999416 0.00003495 0.0000167 0.00000683]] 0 : kai
  • 추론 결과에 따라 다음과 같이 비프음이 들린다.

    • kai >> 1회
    • bai >> 2회
    • bo >> 3회
    • none >> 4회


실습 전체 코드 [다운로드]