현재 사용하고 있는 tf2 내에 opencv를 설치
conda install opencv
pip install cvlib
얼굴 인식 프로그램을 만들기 전, cv라이브러리 내 딥러닝을 통해 얼굴을 인식하게 만들어놓은 라이브러리를 그대로 사용해볼 예정이다!
import cv2
import cvlib as cv
image = cv2.imread('sample.png')
faces, confidences = cv.detect_face(image)
for (x,y,x2,y2), conf in zip(faces, confidences):
#확률 나타내기
cv2.putText(image, str(conf), (x,y-10), cv2.FONT_HERSHEY_PLAIN, 1, (0,255,0),1)
cv2.rectangle(image, (x,y), (x2,y2), (0,255,0), 2)
cv2.imshow('image',image)
key = cv2.waitKey(0)
cv2.destroyAllWindows()
cv2 이미지다루기
imread(filename)
: 이미지 다루기
- filename : 절대, 상대경로 가능
- return : np.ndarray(3차원 BGR 타입)
imshow(title, image)
: 이미지를 사이즈에 맞게 보여줌
- title : 윈도우 창에 나올 제목
- image : 보여줄 이미지
cv2.waitKey(0)
: 키보드 입력을 대기함
- 0 : 키보드 입력 무한정 대기
- imshow와 짝꿍으로 같이 써줘야함
cv2.destroyAllWindows()
: 화면에 나타난 윈도우 종료
- imshow와 짝꿍으로 같이 써줘야함
cv2를 통해 문자 그리기
cv2.putText(img, text, org, fontFace, fontScale, color, thickness, linetype)
- img : 이미지 파일
- text : 출력문자
- conf : 얼굴 인식 확률
- org : 출력 문자 시작 좌표
- fontFace : 폰트 스타일
- fontScale : 폰트 사이즈
- color : RGB 형태로 나타낼 것
- thickness : 폰트 두께
cv2를 통해 사각형 그리기
cv2.rectangle(img, pt1, pt2, color, thickness)
- img : 이미지 파일
- pt1 : 시작점 좌표
- pt2 : 종료점 좌표
- color : RGB 색상
- thickness : 선의 두께
cv2.VideoCapture() : OpenCV에서 카메라와 비디오로부터 프레임(Frame)을 받아오는 작업 처리하는 클래스
webcam = cv2.VideoCapture(0)#기본카메라 0번 사용
if not webcam.isOpened():
raise Exception("카메라 읎음")
cv2.VideoCapture(index, apiPreference=None)
- index : 기본카메라를 열기 위해서는 인덱스 0
- apiPreference : 선호하는 카메라 처리 방법 지정
- return 값 : retval(cv2.VideoCapture 객체 반환)
- 성공 : True
- 실패 : False
webcam.isOpened()
: 비디오 캡쳐가 준비되었는지 확인
- return 값 : retval(cv2.VideoCapture 객체 반환)
- 성공 : True
- 실패 : False
#프레임 받아오기
ret, frame = webcam.read() #2개의 리턴값을 튜플로 반환함.
if not ret:
raise Exception("캡쳐가 없음")
cv2.VideoCapture().read()
: 성공적으로 웹캠을 열었다면 웹캠으로 사진을 받아옴
- return : 값 2개 반환
- retval(cv2.VideoCapture 객체 반환) : 성공 true, 실패 false
- image : 현재 프레임(numpy.ndarray) ➡️ 캡쳐된 이미지를 받아옴
faces, confidences = cv.detect_face(frame) #이미지에서 얼굴 위치, 얼굴일 확률 받아오기
print(faces)
print(confidences)
cv.detect_face(image)
: OpenCV의 DNN 모듈에서 미리 구현되어있음.
- face : detect한 얼굴 위치 좌표
- confidences : 얼굴일 확률
cv.imwrite('1.jpg', frame)
webcam.release()
cv.imwrite(filename, image)
: 이미지나 동영상 프레임을 다른 이름으로 저장webcam.release()
: 카메라 종료import time
def capture(path, m=1):
count = 0
webcam = cv2.VideoCapture(0)
if not webcam.isOpened():
raise Exception("카메라 읎음")
while count < m:
time.sleep(0.3) # 캡쳐간 시간 0.3로 지연
ret, frame = webcam.read() #2개의 리턴값을 튜플로 반환함.
if not ret:
raise Exception("캡쳐가 없음")
faces, confidences = cv.detect_face(frame)
for face, conf in zip(faces, confidences):
if conf < 0.8:
continue
start_x, start_y, end_x, end_y = faces[0]
cv2.imwrite(path+str(count)+'.jpg', frame[start_y:end_y, start_x:end_x, :])
count += 1
print(count, end='') #캡쳐 완료 시
webcam.release()
capture('/Users/jangsujeong/Downloads/mask_project/nonMask', 300)
import os
non_list = os.listdir('/Users/jangsujeong/Downloads/mask_project/nonMask')
print(non_list)
yes_list = os.listdir('/Users/jangsujeong/Downloads/mask_project/Mask')
print(yes_list)
os.listdir
: 해당 디렉터리에 있는 모든 파일의 목록을 리스트로 받아옴.image = cv2.imread('/Users/jangsujeong/Downloads/mask_project/nonMask/nonMask85.jpg') image.shape #(354, 458, 3)
- image.shape = height, width, channel
- channel : 색상
- 1 : 흑백
- 3 : 컬러
- ‼️Error : AttributeError: 'NoneType' object has no attribute 'shape'
➡️ 보통 imread()에서 경로를 못 읽어와서 나는 에러이므로 경로를 절대경로로 정확히 바꿔줘야 함
w = []
h = []
for i in non_list:
img = cv2.imread('/Users/jangsujeong/Downloads/mask_project/nonMask/' + i)
h.append(img.shape[0])
w.append(img.shape[1])
for i in yes_list:
img = cv2.imread('/Users/jangsujeong/Downloads/mask_project/Mask/' + i)
h.append(img.shape[0])
w.append(img.shape[1])
img_w, img_h = 140, 180
images = [] #실제 데이터
labels = [] #정답 데이터(1,0으로 분류)
for i in non_list:
image = load_img('/Users/jangsujeong/Downloads/mask_project/nonMask/' + i, target_size=(img_w, img_h))
image = img_to_array(image)
images.append(image)
labels.append(0)#마스크 쓰지 않았으므로 0
for i in yes_list:
image = load_img('/Users/jangsujeong/Downloads/mask_project/Mask/' + i, target_size=(img_w, img_h))
image = img_to_array(image)
images.append(image)
labels.append(1)#마스크 썼기 때문에 1
images[0].shape
#(140, 180, 3)
from sklearn.model_selection import train_test_split
import numpy as np
x_train, x_test, y_train, y_test = train_test_split(np.array(images), np.array(labels), test_size=0.2)
x_train, x_val, y_train, y_val = train_test_split(x_train, y_train, test_size=0.1)
model = Sequential()
model.add(Conv2D(32, kernel_size=(3, 3), input_shape=(img_w, img_h, 3), activation='relu'))
model.add(Conv2D(64, (3, 3), activation='relu'))
model.add(MaxPool2D(pool_size=2))
model.add(Dropout(0.25))
model.add(Flatten())
model.add(Dense(128, activation='relu'))
model.add(Dropout(0.5))
model.add(Dense(10, activation='softmax'))
model.compile(loss='categorical_crossentropy', optimizer='adam', metrics=['accuracy'])
history = model.fit(X_train, Y_train, validation_data=(X_test, Y_test), epochs=10, batch_size=5)
# 학습이 너무 오래걸려서 에포크 사이즈를 줄였음
accuracy = history.history['accuracy']
val_accuracy = history.history['val_accuracy']
loss = history.history['loss']
val_loss = history.history['val_loss']
epoch_range = range(20)
plt.figure(figsize=(16,8))
plt.subplot(1,2,1)
plt.plot(epoch_range, accuracy, label='Training Accuaracy')
plt.plot(epoch_range, val_accuracy, label='Validation Accuaracy')
plt.legend(loc='lower right')
plt.title('Training and Validation Accuracy')
plt.subplot(1,2,2)
plt.plot(epoch_range, loss, label='Training Loss')
plt.plot(epoch_range, val_loss, label='Validation Loss')
plt.legend(loc='upper right')
plt.title('Training and Validation Loss')
plt.show()
test_loss, test_accuracy = model.evaluate(x_test, y_test, verbose=0)
test_prediction = np.argmax(model.predict(x_test), axis=-1)
plt.figure(figsize=(13,13))
s = 0
for i in range(25):
plt.subplot(5,5,i+1)
plt.grid(False)
plt.xticks([])
plt.yticks([])
prediction = test_prediction[s+i]
actual = y_test[s+i]
col = 'g'
if prediction!=actual:
col='r'
plt.xlabel('Actual={} || Pred={}'.format(actual, prediction), color=col)
plt.imshow(array_to_img(x_test[s+i]))
plt.show()
안녕하세요, 잘 읽고 공부하고 있는 병아리 입니다!
따라하다가, 모르는 것이 생겨 질문드리려고 댓글 답니다.
모델학습을 하려고 하면, ValueError: Shapes (None, 1) and (None, 10) are incompatible
라는 오류가 나오는데, 거슬러 올라가니 y_train.shape의 값이 누락되었고, "y_val:", y_val.shape의 값에 문제가 생깁니다. 이런 것을 어떻게 해결하셨는지, 혹시 코드 중 누락된 것이 있는지 궁금해서 여쭤봅니다!