AIoT

AIoT 정규 53일차

맥기짱짱 2024. 3. 26. 17:11

- How Flutter works:

  1. Dart 코드 작성: Flutter 앱은 Dart 언어를 사용하여 작성됩니다. Dart는 강력한 타입 시스템과 빠른 JIT(Just-In-Time) 컴파일러를 제공하여 Flutter의 성능과 생산성을 향상시킵니다.
  2. 위젯 사용: Flutter는 위젯이라는 작은 빌딩 블록으로 UI를 작성합니다. 위젯은 모든 것을 나타내며, 화면에 그려지거나 사용자 상호 작용에 반응할 수 있습니다. Flutter는 풍부한 위젯 라이브러리를 제공하며, 이를 조합하여 다양한 UI 디자인을 구축할 수 있습니다.
  3. UI 그리기: Flutter는 Skia 그래픽 엔진을 사용하여 UI를 그립니다. Skia는 Flutter의 모든 그래픽 작업을 처리하며, iOS와 Android에서 하드웨어 가속을 사용하여 빠르고 부드러운 애니메이션을 제공합니다.
  4. 플랫폼 별 엔진 통합: Flutter는 iOS와 Android의 각 플랫폼에 대한 별도의 엔진을 사용합니다. iOS에서는 Flutter가 Objective-C/Swift 코드와 상호 작용하여 네이티브 iOS 앱을 생성하고, Android에서는 Flutter가 Java/Kotlin 코드와 상호 작용하여 네이티브 Android 앱을 생성합니다.
  5. Hot Reload: Flutter의 핵심 기능 중 하나는 "핫 리로드"입니다. 이를 통해 개발자는 앱을 다시 시작할 필요 없이 코드 변경 사항을 즉시 확인할 수 있습니다. 이는 앱을 빠르게 개발하고 디버그하는 데 매우 유용합니다.
  6. 컴파일 및 배포: Flutter 앱은 각 플랫폼에 대해 네이티브 코드로 컴파일됩니다. iOS에서는 Xcode를 사용하여 앱을 빌드하고, Android에서는 Android Studio 또는 Gradle을 사용하여 빌드합니다. 이후 각 플랫폼의 앱 스토어에 배포됩니다.

- 웹캠으로 이미지 캡쳐하기

: 밑에 코드는 웹캠에서 이미지를 캡처하고 사용자별로 이미지를 저장하는 간단한 예제를 제공한다.

# program to capture single image from webcam in python 

# importing OpenCV library 
from cv2 import *

import argparse
import os
import keyboard

import glob # file delete
import shutil #move directory

# initialize the camera 
# If you have multiple camera connected with 
# current device, assign a value in cam_port 
# variable according to that 
cam_port = 0
img_counter = 0
# 비디오 캡처 객체 생성
cam = VideoCapture(cam_port)
# If image will detected without any error, 
# show result 

def getName():
    parser = argparse.ArgumentParser()
    parser.add_argument('second_name', type=str,help="What is the second name?")
    parser.add_argument('first_name', type=str,help="What is the first name?")

    args = parser.parse_args()
    second_name = args.second_name
    first_name = args.first_name
    
    print("Hi %s %s, Let's take a pictures" % (second_name, first_name))

    name = second_name+first_name #write to the with_mask folder

    return name


def makeFolder(name):
    
    # define the name of the directory to be created
    path = "image/" + name
    backup = "image_backup/" + name


    isExist = os.path.exists(path)


    if isExist == True:
        try:
            shutil.move(path,backup)
            os.mkdir(path)

        except OSError:
            print ("Already user name is used, please enter 'y' for update or 'e' for exit")
            if keyboard.is_pressed('e'):
                exit  
    else:
        os.mkdir(path)
        print ("Successfully created the directory %s " % path)
    
def getFile(name,img_counter):
    # define the name of the directory to be created
    path = "image/" + name

    isExist = os.path.exists(path)  
    print(isExist)
    
    img_name = "./image/"+ name +"/image_{}.jpg".format(img_counter)
    
    return img_name

user_name = getName()
makeFolder(user_name)

while True:

    # reading the input using the camera 
    result, frame = cam.read()
    # showing result, it take frame name and image 
    # output 
 
    cv2.imshow('[Space] for picture ,[Esc] for exit !', frame)
    
    k = cv2.waitKey(1)
    # 'q' 키를 누르면 종료
    if k%256 == 27: # ESC pressed
        break
    elif  k%256 == 32:
        img_counter += 1
        img_name = getFile(user_name,img_counter)
        
        imwrite(img_name, frame)
        
        print("{} written!".format(img_name))
        print("[Space bar] click to take a picture!")
    # saving image in local storage 
    #imwrite("GeeksForGeeks.png", image) 

    # If keyboard interrupt occurs, destroy image 
    # window 
    #waitKey(0) 
    #destroyWindow("GeeksForGeeks") 

# If captured image is corrupted, moving to else part 
#else: 
    #print("No image detected. Please! try again")

# 객체 해제
cap.release()
cv2.destroyAllWindows()


1. `import`문: 필요한 라이브러리를 가져옵니다. 여기서는 OpenCV(cv2), argparse, os, keyboard, glob 및 shutil을 가져옵니다.

2. `cam_port` 및 `img_counter` 변수: 웹캠의 포트 및 이미지 카운터를 초기화합니다.

3. `VideoCapture` 객체: 웹캠에서 비디오를 캡처하기 위해 `VideoCapture` 객체를 생성합니다.

4. `getName()` 함수: 사용자에게 성과 이름을 입력하고 이를 결합하여 사용자의 이름을 반환합니다.

5. `makeFolder(name)` 함수: 사용자의 이름을 받아 새로운 이미지 폴더를 만들거나 기존 폴더를 이동합니다.

6. `getFile(name,img_counter)` 함수: 이미지 파일 이름을 생성하고 반환합니다.

7. `while` 루프: 프로그램이 종료될 때까지 웹캠에서 프레임을 읽고, 사용자에게 화면을 보여줍니다.

8. 사용자가 `Space` 키를 누르면 이미지가 캡처되고 저장됩니다.

9. `Esc` 키를 누르면 프로그램이 종료됩니다.

10. 프로그램이 종료되면 웹캠 및 OpenCV 창이 닫힙니다.

 

- 이미지 얼굴인식(이미지 분류 모델):

# 합성곱 신경망(CNN)을 사용한 이미지 분류 모델
# -*- coding: utf-8 -*-
"""
Created on Fri Oct 30 20:07:49 2020

@author: kimrujin
"""

from PIL import Image # pip install Pillow
import os, glob
import numpy as np
import matplotlib.pyplot as plt
from sklearn.model_selection import train_test_split

from keras.models import Sequential
from keras.layers import MaxPooling2D
from keras.layers import Conv2D
from keras.layers import Activation, Dropout, Flatten, Dense
import numpy as np
import os

#import keyboard
import argparse

#240314
#240325   사진으로 수정

epochs = 100

def main():
	test_person = ""
	# 이미지 사이즈
	image_w = 64 
	image_h = 64

	train = input("학습 데이터 방식 선택하세요: type train or load:")

	categories = []   #["Iyou","Janghyk","KimElli","KimRuJin","Mam"]

	# 
	accident_dir = "./image"

	my_dirs = [d for d in os.listdir(accident_dir) if os.path.isdir(os.path.join(accident_dir, d))]

	for person in my_dirs:
		#print(person)
		test_person = person # 테스트 이미지는 항상 마지막 사람 test.jpg
		categories.append(person)


	for person in categories:
		print(person)


	nb_classes = len(categories)

	pixels = image_w * image_h * 3

	X = []
	Y = []
	for idx, cat in enumerate(categories):
	
		label = [0 for i in range(nb_classes)]
		label[idx] = 1
		# 이미지 처리, 피처데이터, 라벨링 생성
		image_dir = accident_dir + "/" + cat
		files = glob.glob(image_dir+"/*.jpg") #사용자가 제시한 조건에 맞는 파일명을 리스트 형식으로 반환
        # crop_img = image.crop([x1,y1,x3,y3])  이미지를 원하는 박스로 자르고 싶을 경우 Image.crop 함수를 사용
		for i, f in enumerate(files):
			img = Image.open(f) #출력은 (width, height)의 튜플 형태로 출력
			img = img.convert("RGB")
			img = img.resize((image_w, image_h))
			data = np.asarray(img)      # numpy 배열로 변환
			print(data.shape)
			X.append(data)
			Y.append(label)
	#        if i % 10 == 0:
	#            print(i, "\n", data)
	X = np.array(X)
	Y = np.array(Y)
	# 데이터 나누기
	X_train, X_test, y_train, y_test = train_test_split(X, Y)
	xy = (X_train, X_test, y_train, y_test)

	#np.save("./image/7obj.npy", xy) # 모든 정보를 저장할 수도 있다...
    #나중에 불러 올 수도 있다.
	#X_train, X_test, y_train, y_test = np.load("./image/7obj.npy")
    
	print("len(Y):", len(Y))

	nb_classes = len(categories) # 레이블 사이즈(종류)

	#image_w = 64
	#image_h = 64
	 
	X_train = X_train.astype("float") / 256  #실수로 변경하기
	X_test  = X_test.astype("float")  / 256
	

	print('X_train shape:', X_train.shape,"X_train.shape[1:]:",X_train.shape[1:])

	input('디버그 용입니다. 엔터를 치세요')
    
	model = Sequential()
	model.add(Conv2D(32, (3, 3), input_shape=X_train.shape[1:], padding='same'))
	model.add(Activation('relu'))

	model.add(MaxPooling2D(pool_size=(2, 2)))
	model.add(Dropout(0.25))

	model.add(Conv2D(64, (3, 3), padding='same'))
	model.add(Activation('relu'))

	model.add(Conv2D(64, (3, 3)))
	model.add(MaxPooling2D(pool_size=(2, 2)))
	model.add(Dropout(0.25))


	model.add(Flatten())   
	model.add(Dense(512))  
	model.add(Activation('relu'))
	model.add(Dropout(0.5))

	model.add(Dense(nb_classes))
	model.add(Activation('softmax'))

	model.compile(loss='categorical_crossentropy',  
		optimizer='adam', #optimizer='rmsprop',
		metrics=['accuracy'])

	print(model.summary())

    #모델 저장하기..
	hdf5_file = "./models/face-model.hdf5"

	#if os.path.exists(hdf5_file):
	
	if train == "load":
		model.load_weights(hdf5_file)
	else: #버전에 따라 epches=epochs 또는 nb_epoch=epochs
		model.fit(X_train, y_train, batch_size=16, epochs=epochs) 
		model.save_weights(hdf5_file)


    #검증하기
	score = model.evaluate(X_test, y_test)
	print('loss=', score[0])        # loss
	print('accuracy=', score[1])    # acc


 
	test_image = './image/'+test_person+'/test.jpg'

	print('Test person is ' + test_person + ', test image is' , test_image)

	img = Image.open(test_image)
	img = img.convert("RGB")
	img = img.resize((64,64))
	data = np.asarray(img)
	X = np.array(data)
	X = X.astype("float") / 256
	
	#X = X.reshape(-1, 64, 64,3)
	X = X.reshape(-1, 64, 64,3)

	pred = model.predict(X)  
	result = [np.argmax(value) for value in pred]   # 

	print(pred)    
	print(result)
    
	print('New data category : ',categories[result[0]])




if __name__=="__main__":
    main()



1. 라이브러리 및 모듈 가져오기:
   - `PIL` (Python Imaging Library), `os`, `glob`, `numpy`, `matplotlib.pyplot`, `sklearn.model_selection`, `keras`와 같은 필요한 라이브러리/모듈을 가져옵니다. 뉴럴 네트워크를 구축하고 학습하기 위해 사용됩니다.
   - 명령행 인수 구문 분석을 위해 `argparse`도 가져옵니다.

2. 상수 및 변수:
   - `epochs = 100`과 같은 상수가 있습니다.
   - 이미지 너비와 높이를 나타내는 변수 (`image_w` 및 `image_h`)가 있습니다.
   - 훈련 데이터 모드 선택에 대한 사용자 프롬프트 (`train`)가 있습니다.
   - 이미지의 다른 범주(레이블)를 저장하는 목록 `categories`가 있습니다.
   - 이미지가 저장된 디렉터리 경로 (`accident_dir`)가 있습니다.
   - 각 범주를 나타내는 하위 디렉터리를 가져오기 위한 리스트 컴프리헨션이 있습니다.

3. 데이터 준비:
   - 각 범주 디렉터리를 반복하여 이미지를 수집하고, 지정된 차원 (`image_w` 및 `image_h`)으로 크기 조정하고, numpy 배열 (`data`)로 변환하여 이를 저장합니다.
   - `train_test_split`을 사용하여 데이터를 훈련 및 테스트 세트로 분할합니다.

4. 데이터 정규화:
   - 이미지의 픽셀 값을 256으로 나누어 정규화합니다.

5. 모델 아키텍처:
   - Keras를 사용하여 순차 모델을 정의합니다.
   - 합성곱 레이어 (`Conv2D`), 활성화 레이어 (`Activation`), 최대 풀링 레이어 (`MaxPooling2D`), 드롭아웃 레이어 (`Dropout`)를 추가합니다.
   - 출력을 펼치고 완전히 연결된 레이어 (`Dense`)와 활성화 함수를 추가합니다.
   - 손실 함수, 옵티마이저 및 평가 메트릭으로 모델을 컴파일합니다.

6. 모델 훈련:
   - 훈련 데이터를 사용하여 모델을 훈련합니다.
   - 훈련된 모델 가중치를 파일 (`face-model.hdf5`)에 저장합니다.

7. 모델 평가:
   - 테스트 데이터로 훈련된 모델을 평가합니다.
   - 손실과 정확도를 출력합니다.

8. 예측:
   - 사용자가 지정한 테스트 이미지를 로드합니다.
   - 테스트 이미지를 훈련 데이터와 유사하게 전처리합니다.
   - 훈련된 모델을 사용하여 테스트 이미지에 대한 예측을 수행합니다.
   - 예측된 범주를 출력합니다.



9. 메인 함수:
   - `main()` 함수는 데이터 로드, 모델 생성, 훈련, 평가 및 예측을 포함한 전체 프로세스를 조정합니다.

10. 실행:
    - 마지막으로, `main()` 함수가 호출되어 전체 스크립트가 실행됩니다.

 

'AIoT' 카테고리의 다른 글

AIoT 정규 55일차  (0) 2024.03.28
AIoT 정규 54일차  (0) 2024.03.27
AIoT 정규 52일차  (0) 2024.03.25
AIoT 정규 51일차  (0) 2024.03.21
AIoT 정규 50일차  (3) 2024.03.14