1. 코드

import sys
from PyQt5.QtWidgets import *
from PyQt5.QtGui import *
from PyQt5.QtCore import *
import numpy as np #pip install numpy
import tensorflow as tf  
# pip install --upgrade pip
# pip install tensorflow

# python이 32bit으로 깔려있다면, 오류가 남 -> window에서 지워주시고 다시 64비트로 설치해주세요.
# ERROR: Could not find a version that satisfies the requirement tensorflow (from versions: none)
# ERROR: No matching distribution found for tensorflow

class 무인가게프로그램(QMainWindow):

    def __init__(self):
        super().__init__()
        self.UI초기화()

    def UI초기화(self):
        self.예측정보리스트 = {
            0 : ["티셔츠", 5000], 
            1 : ["트라우저 진", 30000], 
            2 : ["스웨터", 15000], 
            3 : ["드레스", 50000], 
            4 : ["코트", 50000], 
            5 : ["샌들", 10000], 
            6 : ["셔츠", 15000], 
            7 : ["스니커즈", 30000], 
            8 : ["가방", 5000], 
            9 : ["부츠", 40000]}
        

        self.가게이름 = QLabel('라이캣의 무인가게', self)
        self.가게이름.setFont(QFont("Decorative", 20))
        self.가게이름.adjustSize()
        self.가게이름.move(180, 30)

        self.이미지 = QLabel(self)
        self.이미지.move(170, 100)
        
        self.가이드 = QLabel('File을 눌러 모델 추가 후 이미지 삽입하여 인식', self)
        self.가이드.move(150, 500)
        self.가이드.adjustSize()

        self.계좌번호 = QLabel('(주)생선가게 위니브은행 999-999999-9999', self)
        self.계좌번호.move(200, 550)
        self.계좌번호.adjustSize()
        self.계좌번호.setHidden(True)

        self.이미지업로드 = QPushButton("이미지 업로드", self)
        self.이미지업로드.move(170, 430)
        self.이미지업로드.setEnabled(False)
        self.이미지업로드.clicked.connect(self.loadImage)

        self.결제버튼 = QPushButton("결제하기", self)
        self.결제버튼.move(370, 430)
        self.결제버튼.setEnabled(False)

        self.인식모델 = None

        메뉴바 = self.menuBar() 
        메뉴바.setNativeMenuBar(False)
        파일메뉴 = 메뉴바.addMenu('File')

        모델불러오기메뉴 = QAction('모델 불러오기', self) 
        모델불러오기메뉴.setShortcut('Ctrl+L')
        모델불러오기메뉴.triggered.connect(self.loadModel)
        파일메뉴.addAction(모델불러오기메뉴)

        self.setWindowTitle('무인상점 만들기')
        self.setGeometry(300, 300, 600, 600)
        self.show()

    def loadModel(self):

        try:
            모델파일, _ = QFileDialog.getOpenFileName(self, '모델 추가', '')

            if 모델파일:
                self.인식모델 = tf.keras.models.load_model(
                    모델파일)
                self.가이드.setText('모델 추가 완료!')

            self.이미지업로드.setEnabled(True)
        except:
            self.가이드.setText("모델 파일이 아닙니다.")

    def loadImage(self):

        이미지이름 = QFileDialog.getOpenFileName(self, 'Open file', './')
        이미지파일 = QPixmap(이미지이름[0]).scaled(
            300, 300, aspectRatioMode=Qt.KeepAspectRatio)
        self.이미지.setPixmap(이미지파일)
        self.이미지.adjustSize()

        if 이미지파일:

            행렬 = np.zeros((28, 28))  
            for 행 in range(28):
                for 열 in range(28):
                    행렬[열, 행] = 1 - QImage(QPixmap(이미지이름[0]))\\
                        .scaled(28,28).pixelColor(행, 열).getRgb()[0] / 255.0
                    # 이미지를 압축시켜 음영의 효과로 구분하여 요소들을 추가
            행렬 = 행렬.reshape(-1, 28, 28)

            예측 = self.인식모델.predict(행렬)[0]  # 이미지 인식 진행
            결과 = np.argmax(예측)  # 제일 높게 나온 예측 값
            self.가이드.setText("선택하신 제품은 " + str(self.예측정보리스트.get(결과)[0])\\
                + "이고 결재하실 금액은 "\\
                + "{:,}".format(self.예측정보리스트.get(결과)[1])\\
                + '원 입니다.')
           
            self.가이드.adjustSize()
            self.가이드.move(150, 500)

            self.계좌번호.setHidden(False)  
            self.결제버튼.setEnabled(True)  

프로그램무한반복 = QApplication(sys.argv)
실행인스턴스 = 무인가게프로그램()
프로그램무한반복.exec_()

4. 상세 내용

여기서는 MNIST라고 하는 예제를 사용해서 간단하게 사물인식을 해볼 예정인데요. MNIST라고 한다면 인공지능을 처음 공부해보시는 분들이 print('hello world')처럼 가장 처음에 하시는 예제입니다.

그중에서도 fashion에 관련해서 여러가지 사물을 인식할 수 있는 MNIST를 해보도록 하겠습니다. (기초 MNIST는 손글씨 인식하기 입니다.)

https://s3-us-west-2.amazonaws.com/secure.notion-static.com/f5532a3f-91bd-45aa-a39e-49112c558658/15.png

https://s3-us-west-2.amazonaws.com/secure.notion-static.com/393df86d-d889-49d9-a161-ebb2ee0afe92/16.png

  1. GUI 설계

    self.store = QLabel('라이캣의 무인가게', self)
    self.store.setFont(QFont("Decorative", 20))
    self.store.adjustSize()
    self.store.move(180, 30)
    
    self.label = QLabel(self)  
    self.label.move(170, 100)
    
    self.label2 = QLabel('File을 눌러 모델 추가 후 이미지 삽입하여 인식', self)
    self.label2.move(150, 500)
    self.label2.adjustSize()
    
    self.label3 = QLabel('(주)생선가게 위니브은행 999-999999-9999', self)
    self.label3.move(200, 550)
    self.label3.adjustSize()
    self.label3.setHidden(True)
    
    self.uploadPicture = QPushButton("사진 업로드", self)
    self.uploadPicture.move(170, 430)
    self.uploadPicture.setEnabled(False)
    self.uploadPicture.clicked.connect(self.loadImage)
    
    
    self.Model = None
    
    menubar = self.menuBar() 
    menubar.setNativeMenuBar(False)
    filemenu = menubar.addMenu('File')
    
    load_model = QAction('모델 불러오기', self) 
    load_model.setShortcut('Ctrl+L')
    load_model.triggered.connect(self.loadModel)
    filemenu.addAction(load_model)
    

    여기서 어떻게 물체를 인식할 수 있는지, 머신러닝은 어떻게 학습을 하는지는 강의의 범주를 넘어선다 생각하여 아래 문서로 대체합니다. 영상 강의에서는 이 부분을 좀 더 상세하게 다룹니다.

  2. 인식 모델은 어떻게 동작할까?

    첫 번째 신경망 훈련하기: 기초적인 분류 문제 | TensorFlow Core

    패션 MNIST 데이터셋 신경망 사용법 튜토리얼

    모델 저장과 복원 | TensorFlow Core

    모델 저장과 복원

    머신러닝1 - 생활코딩

    생활 코딩 홈페이지의 머신러닝 관련된 자료입니다.

    Rubiel1/Fashion-Mnist-trained

    학습된 모델을 다운 받을 수 있는 깃허브 페이지입니다.

    https://s3-us-west-2.amazonaws.com/secure.notion-static.com/be5fcbcf-93de-4cc1-b731-4b70e71d64ce/Untitled.png

  3. 이미지 추가 함수 작성

    def loadImage(self):
    
            iname = QFileDialog.getOpenFileName(self, 'Open file', './')
            image = QPixmap(iname[0]).scaled(
                300, 300, aspectRatioMode=Qt.KeepAspectRatio)
            # 라벨에 표시해주기 위해 압축을 진행
            self.label.setPixmap(image)
            self.label.adjustSize()
    

5. 실행 화면

https://s3-us-west-2.amazonaws.com/secure.notion-static.com/1f19c629-4df6-4d68-9f46-7526e68d5442/Untitled.png