일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 | 31 |
- clone coding
- JavaScript
- Instagrame clone
- python
- TeachagleMachine
- coding
- 리액트네이티브
- kaggle
- selenium
- 클론코딩
- 카트폴
- 강화학습 기초
- expo
- ReactNative
- 조코딩
- 강화학습
- Ros
- 정치인
- 크롤링
- 딥러닝
- 머신러닝
- React
- App
- pandas
- 데이터분석
- 전국국밥
- 앱개발
- 사이드프로젝트
- FirebaseV9
- redux
- Today
- Total
qcoding
2) React + Teachable machine 프로젝트 - Teachable Machine 모델 생성 본문
* 이번 글에서는 이미지 수집 -> 분류 -> 모델 생성을 통하여 Teachable Machine을 통해 머신러닝 모델을 생성하는 과정을 정리하였다.
* Teachable Model 생성
1) 이미지 수집
-> 사용 방법 : 구글의 사이트의 이미지 검색을 통하여 검색어를 입력하고 python selenium을 통해 이미지를 가져와서 저장한다.
-> python의 selenium을 통해서 수행하였으며 해당 코드 및 설치방법은 구글링을 통해서 많이 구할 수 있다. 내경우는 배열에 필요한 인물의 이름을 입력하고 반복문을 통해서 여러명의 사진을 한번에 받도록 사용하였다.
한 인물당 200장의 사진을 받도록 하였다.
* 참고 url
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
import time
import urllib.request
import os
def create_dir(directory):
try:
if not os.path.exists(directory):
os.makedirs(directory)
except OSError:
print("Error: Failed to create the directory.")
def image_Crawling(person):
driver = webdriver.Chrome()
driver.get("https://www.google.co.kr/imghp?hl=ko&tab=wi&authuser=0&ogbl")
elem = driver.find_element_by_name("q")
elem.send_keys(person)
elem.send_keys(Keys.RETURN)
# 이미지가 로딩될 때 까지 기다리는 코드
SCROLL_PAUSE_TIME = 1
# Get scroll height
# 브라우저 높이를 찾음
last_height = driver.execute_script("return document.body.scrollHeight")
while True:
# Scroll down to bottom
# 브라우저를 내린다음 로딩이 될 때까지 기다려줌. 여기서는 1초 인데, 이미지 로드에 따라서 시간 조정 필요
driver.execute_script("window.scrollTo(0, document.body.scrollHeight);")
# Wait to load page
time.sleep(SCROLL_PAUSE_TIME)
# Calculate new scroll height and compare with last scroll height
new_height = driver.execute_script("return document.body.scrollHeight")
if new_height == last_height:
try:
driver.find_element_by_css_selector(".mye4qd").click()
except:
break
last_height = new_height
// 이미지 전체 태그를 가져온 다음 한개씩 이미지를 클릭하여 url을 가져와서 다운로드
imgs = driver.find_elements_by_css_selector(".rg_i.Q4LuWd")
dir = ".\idols" + "\\" + person
create_dir(dir) #폴더 생성
count = 1
for img in imgs:
try:
img.click()
time.sleep(2)
imgUrl = driver.find_element_by_xpath(
'//*[@id="Sva75c"]/div/div/div[3]/div[2]/c-wiz/div/div[1]/div[1]/div[2]/div[1]/a/img').get_attribute(
"src")
path = f"이미지를 저장할 경로\\{person}"
urllib.request.urlretrieve(imgUrl, path + person + str(count) + ".jpg")
count = count + 1
# 사진을 몇 장까지 사용할 것 인지에 대한 분류
if count >= 200:
break
except:
pass
driver.close()
person_array = ["트럼프 얼굴","Trumph","오바마 얼굴"]
for person in person_array:
image_Crawling(person)
# 크롤링 동작 모습
2) 이미지 분류
-> 위에서 이미지를 수집하였으면 이제 이미지를 분류하는 일이 남아있다. 내 경우에는 총 20명의 유명 정치인을 크롤링하였으므로, 최종 사진은 20명 * 200장 = 총 4,000장의 사진이 생겼다. 그러나 이 사진을 바로 사용해서 학습할 경우 모델의 정확도가 매우 떨어지게 된다. (인공지능 모델은 Garbage In Garbage out 이란 말로 학습에 들어가는 데이터가 매우 중요하다. ) 내 경우 사이트 이용자의 얼굴을 받아 총 20명의 정치인과 가장 유사한 정치인을 선택하는 것으로 이 떄 사용할 사진은 사용자의 정면 얼굴 사진이 될 것 이다. 그러므로 아래와 같이 학습에 부적절한 사진들을 제거해 주어야 한다.
매우 매우 어렵고 귀찮은 일이 될 것 이다. 이를 위해 python opnecv를 이용하여 얼굴 부분을 검출하고 얼굴부분에 해당하는 사진만을 잘라내서 학습에 필요한 사진을 생성하려고 한다. 아래와 같이 haar Cascade를 사용할 것이며, 해당 알고리즘에 대한 설명은 아래의 참고 링크를 보면 설명이 되어 있다.
Haar Cascade ( haarcascade_frontface.xml )
- 머신 러닝기반의 오브젝트 검출 알고리즘
- 비디오 또는 이미지에서 오브젝트 검출
- 찾으려는 오브젝트(여기에선 얼굴)가 포함된 이미지와 오브젝트가 없는 이미지를 사용하여 Haar Cascade Classifier(하르 특징 분류기)를 학습
- 분류기를 사용하여 오브젝트 검출
https://webnautes.tistory.com/1352
아래 해당 코드를 실행하면 작동하며, 여기서 내가 시간을 보냈던 2가지 부분이 있다. 바로 한글이 들어간 경우로
아래의 2가지로 분류할 수 있다.
1) 원본사진 불러올 때 한글이 들어간 파일 불러오기 ( 폴더 또는 파일에 한글 사용) - Imread
// path 에 한글이 들어있는 경우
full_path = f"{path}/{idol}/{imgNum}.jpg"
// numpy를 사용하여 인코딩하여 사용함
with open(full_path, 'rb') as f:
data = f.read()
encoded_img = np.frombuffer(data, dtype=np.uint8)
// imdecode를 통해 디코딩하여 사용함.
img_org = cv2.imdecode(encoded_img, cv2.IMREAD_COLOR)
2) 원본사진에서 얼굴부분을 검출하고, 얼굴 부분을 잘라서 새로운 파일로 저장할 때 - Imwrite 시
// 이미지 저장함수로 잘될 시 True를 return함
def image_write(filename, img, params=None):
try:
ext = os.path.splitext(filename)[1]
result, n = cv2.imencode(ext, img, params)
if result:
with open(filename, mode='w+b') as f:
n.tofile(f)
return True
else:
return False
except Exception as e:
print(e)
return False
// 함수에 파일명을 넣어서 결과를 return 받고 True일 경우 이미지가 잘 저장된 것을 확인
response=image_write(f'{save_path}/{imgNum}.png',cropped)
# cv2.imwrite(f"./detection/{imgNum}.png", cropped)
if response:
print("이미지 저장")
위의 2가지 부분을 잘 사용하여 아래의 전체 코드를 작성하였다.
# -*- coding: utf-8 -*-
import cv2
import numpy as np
import os
import keyboard
face_cascade = cv2.CascadeClassifier(cv2.data.haarcascades + 'haarcascade_frontalface_default.xml')
eye_cascade = cv2.CascadeClassifier('haarcascades/haarcascade_eye.xml')
path = 'D:/개발/web_개발/crwaling'
idols = ['강호동 얼굴', '고현정 얼굴', '공유 얼굴', '공효진 얼굴', '김강우 얼굴', '김다미 얼굴', '김대명 얼굴', '김범수 얼굴', '김우빈 얼굴', '김유정 얼굴', '김종국 얼굴', '김태리 얼굴', '김태희', '다니엘헤니 얼굴', '려원 얼굴', '로제 얼굴', '류준열 얼굴', '문채원 얼굴', '박경림', '배두나 얼굴', '뷔 얼굴', '서은광 얼굴', '손예진 얼굴', '송중기 얼굴', '신민아 얼굴', '오지호 얼굴', '윤아 얼굴', '윤은혜 얼굴', '이민정 얼굴', '이병헌 얼굴', '이서진 얼굴', '이솜 얼굴', '이윤석 얼굴', '이이경 얼굴', '임시완 얼굴', '정유미 얼굴', '정지찬 얼굴', '정형돈 얼굴', '존박 얼굴', '청하 얼굴', '태연 얼굴', '트럼프 얼굴', '한소희 얼굴']
def image_write(filename, img, params=None):
try:
ext = os.path.splitext(filename)[1]
result, n = cv2.imencode(ext, img, params)
if result:
with open(filename, mode='w+b') as f:
n.tofile(f)
return True
else:
return False
except Exception as e:
print(e)
return False
for idol in idols:
os.mkdir(f'./detection/{idol}')
print(f"{idol} 폴더가 생성되었습니다.")
imgNum = 1
while imgNum <= 199:
full_path = f"{path}/{idol}/{imgNum}.jpg"
try:
with open(full_path, 'rb') as f:
data = f.read()
encoded_img = np.frombuffer(data, dtype=np.uint8)
img_org = cv2.imdecode(encoded_img, cv2.IMREAD_COLOR)
gray = cv2.cvtColor(img_org, cv2.COLOR_BGR2GRAY)
faces = face_cascade.detectMultiScale(gray, 1.3, 5)
if len(faces) > 0 :
for (x, y, w, h) in faces:
cropped = img_org[y - int(h / 4):y + h + int(h / 4), x - int(w / 4):x + w + int(w / 4)]
print(f"{imgNum}사진 face 찾기 성공")
# 이미지를 저장
# 저장 경로
save_path = f'D:/개발/web_개발/crwaling/face_detection/detection/{idol}'
# print(save_path)
# cv2.imwrite(os.path.join(os.path.abspath(os.path.dirname(__file__)), f'{imgNum}.png'), cropped)
# cv2.imwrite(f"./detection/gain/"+"face" + str(imgNum) + ".png", cropped)
response = image_write(f'{save_path}/{imgNum}.png', cropped)
if response:
print("이미지 저장완료")
cv2.destroyAllWindows()
pass
imgNum += 1
# roi_gray = gray[y:y+h, x:x+w]
# roi_color = img[y:y+h, x:x+w]
# eyes = eye_casecade.detectMultiScale(roi_gray)
# for (ex, ey, ew, eh) in eyes:
# cv2.rectangle(roi_color, (ex,ey), (ex+ew, ey+eh),(0,255,0),2)
else:
print(f"{imgNum}사진 face 찾기 실패")
imgNum += 1
except:
print("error 발생")
imgNum += 1
pass
print(f"{idol} 사진찾기 완료")
추가로 사진을 보면 내가 원하는 인물이 아닌 다른 인물도 등장하여, 얼굴을 검출을 잘하긴 하지만 내가 원하는 인물이 아닌 경우가 있을 수 있다. 이를 위해서 한개씩 인물을 보면서 내가 찾는 인물이 맞으면 키보드 s를 누르고 아니면 d를 눌러서 저장을 하지 않게 코드를 수정하였다.
여기서 사용되는 haarcascade_frontalface_default.xml 파일은 아래에서 받을 수 있다.
https://github.com/leeminq1/opencv_face_detection
import cv2
import numpy as np
import os
import keyboard
face_cascade = cv2.CascadeClassifier(cv2.data.haarcascades + 'haarcascade_frontalface_default.xml')
eye_cascade = cv2.CascadeClassifier('haarcascades/haarcascade_eye.xml')
path = 'D:/개발/crwaling'
idols = ['가인 얼굴', '강호동 얼굴']
def image_write(filename, img, params=None):
try:
ext = os.path.splitext(filename)[1]
result, n = cv2.imencode(ext, img, params)
if result:
with open(filename, mode='w+b') as f:
n.tofile(f)
return True
else:
return False
except Exception as e:
print(e)
return False
for idol in idols:
os.mkdir(f'./detection/{idol}')
print(f"{idol} 폴더가 생성되었습니다.")
imgNum = 1
while imgNum <= 199:
full_path = f"{path}/{idol}/{imgNum}.jpg"
img_array = np.fromfile(full_path, np.uint8)
img_org = cv2.imdecode(img_array, cv2.IMREAD_COLOR)
img_drawn=img_org.copy()
gray = cv2.cvtColor(img_org, cv2.COLOR_BGR2GRAY)
faces = face_cascade.detectMultiScale(gray, 1.3, 5)
try:
if len(faces) > 0 :
for (x, y, w, h) in faces:
cropped = img_org[y - int(h / 4):y + h + int(h / 4), x - int(w / 4):x + w + int(w / 4)]
print(f"{imgNum}사진 face 찾기 성공")
# 이미지를 저장
# 저장 경로
save_path = f'D:/개발/crwaling/face_detection/detection/{idol}'
# print(save_path)
# cv2.imwrite(os.path.join(os.path.abspath(os.path.dirname(__file__)), f'{imgNum}.png'), cropped)
# cv2.imwrite(f"./detection/gain/"+"face" + str(imgNum) + ".png", cropped)
cv2.rectangle(img_drawn, (x, y), (x + w, y + h), (255, 0, 0), 2)
cv2.imshow('Image view', img_drawn)
cv2.waitKey(0)
if keyboard.read_key() == "s":
print("이미지 저장 요청")
response = image_write(f'{save_path}/{imgNum}.png', cropped)
# cv2.imwrite(f"./detection/{imgNum}.png", cropped)
if response:
print("이미지 저장완료")
cv2.destroyAllWindows()
pass
elif keyboard.read_key() == "d":
print("이미지 저장 요청 안함")
cv2.destroyAllWindows()
pass
imgNum += 1
# roi_gray = gray[y:y+h, x:x+w]
# roi_color = img[y:y+h, x:x+w]
# eyes = eye_casecade.detectMultiScale(roi_gray)
# for (ex, ey, ew, eh) in eyes:
# cv2.rectangle(roi_color, (ex,ey), (ex+ew, ey+eh),(0,255,0),2)
else:
print(f"{imgNum}사진 face 찾기 실패")
imgNum += 1
except:
print("error 발생")
imgNum += 1
pass
* 파이썬 얼굴 검출 코드 실행 화면
3) 모델 생성
-> 마지막으로 실제 모델을 생성하는 부분이다. 이 부분은 위의 부분에 비해서 매우 쉽다. 그냥 이미지가 저장되어 있는 폴더를 넣어주기만 하면된다. 아래의 사진을 참고하자.
https://teachablemachine.withgoogle.com/
위와 같이 사진을 업로드하고 모델을 학습하면 json의 형태로 다운로드 하거나 업로드하여 호스팅을 이용할 수 있다. 내 경우는 업로드하여 호스팅하는 방법을 선택하였다.
또한 아래를 보면 자바스크립트 코드를 통해 모델을 불러올 수 있는 스니펫이 있다.
호스팅을 완료하면 최종적으로 url을 받을 수 있다. 내 경우에는 아래와 같은 모델을 받았으며 react에서 해당모델을 통해서 사이트를 만들어 보도록 하자
https://teachablemachine.withgoogle.com/models/KAoZrcPlp/
'React' 카테고리의 다른 글
4) React + Teachable machine 프로젝트 - 배포 (Firebase Hosting 사용 ) + 카카오 애드핏 광고 적용 (1) | 2022.03.20 |
---|---|
3) React + Teachable machine 프로젝트 - React를 통한 프로젝트 제작 (1) | 2022.03.20 |
1) React + Teachable machine 프로젝트 - 닮은꼴 정치인 찾기 개요 (0) | 2022.03.20 |