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