Nhận diện khuôn mặt ở khoảng cách xa hơn 60cm

Một phần của tài liệu Ứng dụng xử lý ảnh trong nhận diện điều khiển ô tô (Trang 137 - 181)

123

Hoạt động với độ chính xác thấp nếu tầm quan sát của camera đến người lái vượt q 60cm như hình 6.8. Độ chính xác của việc thu nhận thơng tin hình ảnh vào để xử lý sẽ bị nhiễu, gây khó khăn cho việc xử lý, dễ đưa ra kết quả sai lệch cho việc cảnh báo.

6.5 Thuận lợi và khó khăn khi thực hiện đề tài 6.5.1 Thuận lợi 6.5.1 Thuận lợi

Trong quá trình thực hiện được sự hướng dẫn tận tình của Thầy TS. Nguyễn Phụ Thượng Lưu hỗ trợ nhóm về những vấn đề khó giải và chỉnh sửa những lỗi thiếu sót trong q trình thực hiện đồ án.

Đề tài chúng em dựa trên nền tảng của các thiết bị có sẵn trên thị trường nên tài liệu tham khảo có nhiều.

Các phụ tùng có sẵn trên thị trường.

Các thành viên trong nhóm đều có khả năng tìm kiếm và sàng lọc tài liệu nên hoàn thành đồ án đúng thời gian.

6.5.2 Khó khăn

Trong lúc thực hiện đồ án thì tình hình dịch Covid 19 diễn biến phức tạp nên ảnh hưởng nhiều đến việc tập trung nhóm để thảo luận phát triển và thi công đề tài, việc mua phụ tùng cho mơ hình rất khó khăn. Do đó mơ hình hồn thành khơng được tồn vẹn chỉnh chu như dự kiến ban đầu.

Các thuật tốn lập trình cho ngơn ngữ Python và ứng dụng OpenCV cần địi hỏi kỹ năng chun mơn cao, do đó trong lúc thực hiện đồ án gây nhiều khó khăn cho cả nhóm nên sản phẩm của nhóm tạo ra có những sai lệch so với thực tế.

124

6.6 Khả năng phát triển đề tài

Có thể nói vấn đề an tồn khi lái xe là một trong những điều cấp thiết lúc này. Do đó đề tài của nhóm em có khả năng tiếp cận được với thị trường do giá thành thấp, kích thước nhỏ gọn, thích hợp với mọi dịng xe trên thị trường.

Ngồi ra, với việc sử dụng mạch xử lý Raspberry như 1 máy tính thu nhỏ. Ta có thể phát triển đề tài bằng cách tích hợp nhiều ứng dụng khác nhau.

Một khả năng phát triển đề tài như nâng cấp thêm màn hình cảm ứng, kết nối điều khiển với mạch xử lý. Hoạt động quan sát theo dõi hành vi mệt mỏi của người lái xe, đồng thời phát triển mạch như 1 màn hình cảm ứng có thể bật được cái ứng dụng tiện lợi như, nghe nhạc trực tuyến, map chỉ đường...

Hoặc nhận diện vạch kẻ đường để cảnh báo người lái xe đi đúng làn đường của mình...

125

TÀI LIỆU THAM KHẢO

[1]. Lê Thế Hải, Lê Thanh Hòa, “Nhận diện chớp mắt và cảnh báo buồn ngủ khi lái xe trên nền windows và android”, Khoa Điện - Điện tử Viễn Thông, TP. Hồ Chí Minh, 1/2012.

[2]. Thái Thị Hịa Vân, “Nghiên cứu tình trạng buồn ngủ của người lái xe dựa trên nhận dạng cử chỉ khuôn mặt”, Trung tâm Thông tin-Học liệu, Đại học Đà Nẵng, 2017. [3]. Nông Quang Huy, “Nghiên cứu thiết kế thiết bị chống ngủ gật cho lái xe ô tô”, Viện Điện Tử - Viễn Thông, Đại học BKHN, Hà Nội, 2013.

[4]. Th.S Nguyễn Duy Linh, Th.S Trần Cơng Trung, “Tìm hiểu một số hệ thống cảnh báo lái xe ngủ gật (drowsy driver alert system) và đề xuất phương pháp xây dựng ứng dụng với thư viện mã nguồn mở OpenCV”, Tạp chí thơng tin khoa học & Cơng nghệ Quảng Bình, Số 4/2019.

[5]. Gérard Blanchet, Maurice Charbit, “Digital Signal and Image Processing

using MATLAB®”, United States, 2006 by ISTE Ltd.

[6]. Rafael C.Gonzalez, Richard E.Woods, Steven L.Eddins, “Digital Image

Processing using MATLAB®”, United States, 2004 by Pearson Education, Inc. [7]. Thông tư số 17/2010/TT-BGTVT ngày 05/07/2010 ban hành Quy chuẩn kỹ thuật Quốc gia về báo hiệu đường bộ.

[8]. PGS.TS Nguyễn Quang Hoan, “Giáo trình xử lý ảnh”, Học Viện Bưu Chính

Viễn Thơng, Hà Nội, 24/07/2014.

[9]. Chongke Zhong, Jingyuan Yang, Tan Xu, et al, “Serum matrix

metalloproteinas-9 levels and prognosis of acute ischemic stroke”, 26/7/2017, [Online] Available: https://www.neurology.org/.

[10]. Tristan Hearn, “using only their own webcam”, 27/6/2017, [Online] Available:

126

[11]. American Thoracic Society, [Online] Available:

https://www.thoracic.org/patients/patient-resources/resources/sleepiness-and- driving.pdf.

[12]. MLAB, “Raspberry Pi 4 Model B’’07/11/2013, [Online] Available:

https://pivietnam.com.vn/raspberry-pi-4-model-b-pivietnam-com-vn.html

[13]. Hiền Nguyễn, “Python là gì? Đặc điểm của ngơn ngữ lập trình Python”,

27/11/2019. [Online] Available: https://toidayhoc.com/lap-trinh/python-la-gi-dac- diem-cua-ngon-ngu-lap-trinh-python/

[14]. Phạm Trung, “Công nghệ AI giúp cảnh báo buồn ngủ khi lái xe”, 18/12/2019, [Online] Available: https://vnexpress.net/cong-nghe-ai-giup-canh-bao-buon-ngu- khi-lai-xe-4029264.html.

[15]. Tin Học Sóc Trăng, “Tổng quang về OpenCV”, 17/02/2017, [Online] Available: https://www.tinhocsoctrang.com/2017/02/tong-quan-ve-opencv.html

[16]. Công ty TNHH CARCAM Việt Nam, [Online] Available:

https://carcam.vn/thiet-bi-canh-bao-buon-ngu-khi-lai-xe-carcam-carcam-fatigue- warning-system-pd105571.html

127

PHỤ LỤC

PHỤ LỤC 1. CHƯƠNG TRÌNH XỬ LÝ ẢNH TRONG NHẬN DIỆN ĐIỀU KHIỂN Ô TÔ

import numpy as np import time

import pylab

from keras import backend as K import imutils

from keras.models import load_model import keras

import requests

from scipy.spatial import distance as dist from imutils import face_utils

import dlib

import cv2, os, sys import face_recognition import tensorflow as tf

import RPi.GPIO as GPIO ## Import GPIO library

from pygame import mixer # Load the popular external library from datetime import datetime

facial_landmarks_predictor = '68_face_landmarks_predictor.dat' sleep_predictor = dlib.shape_predictor(facial_landmarks_predictor) # Load model predict xem mat nguoi dang dong hay mo

model_hdf5 = load_model('weights.149-0.01.hdf5')

#message: Thong diep hien len man hinh // Thơng điệp hiện lên màn hình #waring_time: Thoi gian canh bao // Thời gian cảnh báo

128 #sound_name: Am Thanh canh bao

waring_config = [ [#=== Th1 { #Lan 1

"message": "Nguoi lai xe nham mat hon 3 giay", "waring_time": 2,

"on_type": 0,

"sound_name": 'sound/th1_1.mp3' },{ #Lan 2

"message": "Nguoi lai xe nham mat hon 7 giay", "waring_time": 2,

"on_type": 0,

"sound_name": 'sound/th1_2.mp3' },{ #Lan 3

"message": "Nguoi lai xe nham mat hon 12 giay", "waring_time": 4, "on_type": 'relay_1', "sound_name": 'sound/th1_3.mp3' } ], [#=== Th2 { #Lan 1

"message": "Khong tim thay khuon mat trong 3s", "waring_time": 2,

"on_type": 0,

"sound_name": 'sound/th2_1.mp3' },{ #Lan 2

"message": "Khong tim thay khuon mat trong 7s", "waring_time": 2,

129 "on_type": 0,

"sound_name": 'sound/th2_2.mp3' },{ #Lan 3

"message": "Khong tim thay khuon mat vuot qua 12s", "waring_time": 4, "on_type": 'relay_1', "sound_name": 'sound/th2_3.mp3' } ], [#=== Th3 { #Lan 1

"message": "Nhip tim vuot qua nguong 50-100 trong 3s", "waring_time": 2,

"on_type": 0,

"sound_name": 'sound/th3_1.mp3' },{ #Lan 2

"message": "Nhip tim vuot qua nguong 50-100 trong 7s", "waring_time": 3,

"on_type": 0,

"sound_name": 'sound/th3_2.mp3' },{ #Lan 3

"message": "Nhip tim vuot qua nguong 50-100 qua 12s", "waring_time": 4, "on_type": 'relay_1', "sound_name": 'sound/th3_3.mp3' } ], [#=== Th4 { #Lan 1

130 "message": "Th4.1", "waring_time": 1, "on_type": 0, "sound_name": 'sound/th4_1.mp3' },{ #Lan 2 "message": "Th4.2", "waring_time": 3, "on_type": 0, "sound_name": 'sound/th4_2.mp3' },{ #Lan 3 "message": "Th4.3", "waring_time": 4, "on_type": 'relay_1', "sound_name": 'sound/th4_3.mp3' } ], ] def resource_path(relative_path):

""" Get absolute path to resource, works for dev and for PyInstaller """ try:

# PyInstaller creates a temp folder and stores path in _MEIPASS base_path = sys._MEIPASS

except Exception:

base_path = os.path.abspath(".")

return os.path.join(base_path, relative_path)

131 class FacialLandMarksPosition: left_eye_start_index, left_eye_end_index = face_utils.FACIAL_LANDMARKS_IDXS["left_eye"] right_eye_start_index, right_eye_end_index = face_utils.FACIAL_LANDMARKS_IDXS["right_eye"] def resource_path(relative_path):

""" Get absolute path to resource, works for dev and for PyInstaller """ try:

# PyInstaller creates a temp folder and stores path in _MEIPASS base_path = sys._MEIPASS

except Exception:

base_path = os.path.abspath(".")

return os.path.join(base_path, relative_path)

class findFaceGetPulse(object):

def __init__(self, bpm_limits=[], data_spike_limit=250, face_detector_smoothness=10): self.frame_in = np.zeros((10, 10)) self.frame_out = np.zeros((10, 10)) self.fps = 0 self.buffer_size = 250 #self.window = np.hamming(self.buffer_size) self.data_buffer = []

132 self.times = [] self.ttimes = [] self.samples = [] self.freqs = [] self.fft = [] self.slices = [[0]] self.t0 = time.time() self.bpms = [] self.bpm = 0 dpath = resource_path("haarcascade_frontalface_alt.xml") if not os.path.exists(dpath):

print("Cascade file not present!")

self.face_cascade = cv2.CascadeClassifier(dpath) self.face_rect = [1, 1, 2, 2] self.last_center = np.array([0, 0]) self.last_wh = np.array([0, 0]) self.output_dim = 13 self.trained = False self.idx = 1 self.find_faces = True self.find_face = False #sleep self.sleep_scale = 0.5 self.count_eye_close = 0 self.curr_state = 0 self.curr_state_list = [] GPIO.setmode(GPIO.BCM)

133 GPIO.setup(21, GPIO.OUT) mixer.init() self.before_time = datetime.now() self.before_time_1 = datetime.now() self.before_time_2 = datetime.now() self.before_time_3 = datetime.now() self.message_warning = False self.curr_warning_type = 0 self.curr_warning_time = 0 self.waring_time = 0 self.estimate = 5 def find_faces_toggle(self):

self.find_faces = not self.find_faces return self.find_faces

def get_faces(self): return

def shift(self, detected): x, y, w, h = detected

center = np.array([x + 0.5 * w, y + 0.5 * h]) shift = np.linalg.norm(center - self.last_center)

self.last_center = center return shift

134 x, y, w, h = rect

cv2.rectangle(self.frame_out, (x, y), (x + w, y + h), col, 1)

def get_subface_coord(self, fh_x, fh_y, fh_w, fh_h): x, y, w, h = self.face_rect

return [int(x + w * fh_x - (w * fh_w / 2.0)), int(y + h * fh_y - (h * fh_h / 2.0)), int(w * fh_w),

int(h * fh_h)]

def get_subface_means(self, coord): x, y, w, h = coord subframe = self.frame_in[y:y + h, x:x + w, :] v1 = np.mean(subframe[:, :, 0]) v2 = np.mean(subframe[:, :, 1]) v3 = np.mean(subframe[:, :, 2]) return (v1 + v2 + v3) / 3. def train(self):

self.trained = not self.trained return self.trained def plot(self): data = np.array(self.data_buffer).T np.savetxt("data.dat", data) np.savetxt("times.dat", self.times) freqs = 60. * self.freqs

idx = np.where((freqs > 50) & (freqs < 180)) pylab.figure()

135 n = data.shape[0] for k in xrange(n): pylab.subplot(n, 1, k + 1) pylab.plot(self.times, data[k]) pylab.savefig("data.png") pylab.figure() for k in xrange(self.output_dim): pylab.subplot(self.output_dim, 1, k + 1) pylab.plot(self.times, self.pcadata[k]) pylab.savefig("data_pca.png") pylab.figure() for k in xrange(self.output_dim): pylab.subplot(self.output_dim, 1, k + 1) pylab.plot(freqs[idx], self.fft[k][idx]) pylab.savefig("data_fft.png") quit()

def run(self, cam):

self.times.append(time.time() - self.t0) self.frame_out = self.frame_in self.gray = cv2.equalizeHist(cv2.cvtColor(self.frame_in, cv2.COLOR_BGR2GRAY)) col = (100, 255, 100) if self.find_faces: detected = list(self.face_cascade.detectMultiScale(self.gray, scaleFactor=1.3, minNeighbors=4, minSize=(50, 50),

136

flags=cv2.CASCADE_SCALE_IMAGE)) if len(detected) > 0:

detected.sort(key=lambda a: a[-1] * a[-2])

if self.shift(detected[-1]) > 10: self.face_rect = detected[-1] if set(self.face_rect) == set([1, 1, 2, 2]): return forehead1 = self.get_subface_coord(0.5, 0.18, 0.25, 0.15) self.draw_rect(forehead1) vals = self.get_subface_means(forehead1) self.data_buffer.append(vals) L = len(self.data_buffer) if L > self.buffer_size: self.data_buffer = self.data_buffer[-self.buffer_size:] self.times = self.times[-self.buffer_size:] L = self.buffer_size processed = np.array(self.data_buffer) if len(self.times) > 0 and len(processed) > 0: while len(self.times) != len(processed): if len(self.times) > len(processed): self.times.pop()

else:

processed.pop() self.samples = processed

137 if L > 10:

self.output_dim = processed.shape[0]

self.fps = float(L) / (self.times[-1] - self.times[0])

even_times = np.linspace(self.times[0], self.times[-1], L) interpolated = np.interp(even_times, self.times, processed) interpolated = np.hamming(L) * interpolated

interpolated = interpolated - np.mean(interpolated) raw = np.fft.rfft(interpolated)

phase = np.angle(raw) self.fft = np.abs(raw)

arran_num = L / 2 + 1 < len(self.fft) and L / 2 + 1 or len(self.fft) self.freqs = float(self.fps) / L * np.arange(arran_num)

freqs = 60. * self.freqs

idx = np.where((freqs > 50) & (freqs < 180)) pruned = self.fft[idx] phase = phase[idx] if len(pruned): pfreq = freqs[idx] self.freqs = pfreq self.fft = pruned idx2 = np.argmax(pruned) t = (np.sin(phase[idx2]) + 1.) / 2. t = 0.9 * t + 0.1 alpha = t beta = 1 - t

138

self.bpm = self.freqs[idx2] + self.estimate self.idx += 1 x, y, w, h = self.get_subface_coord(0.5, 0.18, 0.25, 0.15) r = alpha * self.frame_in[y:y + h, x:x + w, 0] g = alpha * \ self.frame_in[y:y + h, x:x + w, 1] + \ beta * self.gray[y:y + h, x:x + w] b = alpha * self.frame_in[y:y + h, x:x + w, 2] self.frame_out[y:y + h, x:x + w] = cv2.merge([r,g,b]) x1, y1, w1, h1 = self.face_rect self.slices = [np.copy(self.frame_out[y1:y1 + h1, x1:x1 + w1, 1])] text_color = (50, 155, 50)

gap = (self.buffer_size - L) / self.fps self.bpms.append(self.bpm) self.ttimes.append(time.time()) if len(self.bpms) > 10: bpm = sum(self.bpms)/10 self.bpms.pop(0) cv2.putText(self.frame_out, "Bpm: %0.1f " %bpm, (10, 25), cv2.FONT_HERSHEY_PLAIN, 2, text_color)

text = "(estimate: %0.1f bpm)" % (self.bpm) tsize = 1

cv2.putText(self.frame_out, text,

(int(x - w / 2), int(y)), cv2.FONT_HERSHEY_PLAIN, tsize, text_color)

datetime_now = datetime.now()

delta_3 = datetime_now - self.before_time_3 if self.find_face: # tim ra khuon

139

if bpm >= 50 and bpm <= 100:#Nhip tim on dinh thi tat thong bao self.before_time_3 = datetime_now

if self.curr_warning_type == 3: self.curr_warning_time = 0 self.message_warning = False else: # Th3: Cảnh báo nhịp tim

if delta_3.seconds > 12: #Lan3: Nếu thời gian cảnh báo nhắc nhở ban đầu vượt quá 10 giây

if self.curr_warning_type == 3 and self.curr_warning_time != 3: self.turn_on_waring(3,3)

self.curr_warning_time = 0

elif delta_3.seconds >= 7:#Lan2: Khi nhịp tim vượt quá ngưỡng 50-100 bpm trong khoảng thời gian 5 giây

if self.curr_warning_type == 3 and self.curr_warning_time != 2: self.turn_on_waring(3,2)

elif delta_3.seconds >= 3:#Lan1: Khi nhịp tim vượt quá ngưỡng 50-100 bpm trong khoảng thời gian 3 giây

self.turn_on_waring(3,1) else:

if gap:

text = "(estimate: %0.1f bpm, wait %0.0f s)" % (self.bpm, gap) tsize = 1

cv2.putText(self.frame_out, text,

(int(x - w / 2), int(y)), cv2.FONT_HERSHEY_PLAIN, tsize, text_color)

else:

text = "(estimate: %0.1f bpm)" % (self.bpm) tsize = 1

140

(int(x - w / 2), int(y)), cv2.FONT_HERSHEY_PLAIN, tsize, text_color)

# ==== CODE sleep w

def predict_eye_state(self, model, image): # Resize anh ve 20x10

image = cv2.resize(image, (20, 10)) image = image.astype(dtype=np.float32)

# Chuyen thanh tensor

image_batch = np.reshape(image, (1, 10, 20, 1)) # Dua vao mang mobilenet de xem mat dong hay mo

image_batch = keras.applications.mobilenet.preprocess_input(image_batch)

return np.argmax(model.predict(image_batch)[0]) #buon ngu

def run_sleep(self, cam):

# Doc anh tu camera va chuyen thanh RGB

image = cv2.cvtColor(self.frame_in, cv2.COLOR_BGR2RGB)

# Resize anh con 50% kich thuoc goc

original_height, original_width = image.shape[:2]

resized_image = cv2.resize(image, (0, 0), fx=self.sleep_scale, fy=self.sleep_scale)

# Chuyen sang he mau LAB de lay thanh lan Lightness lab = cv2.cvtColor(resized_image, cv2.COLOR_BGR2LAB) l, _, _ = cv2.split(lab)

141 resized_height, resized_width = l.shape[:2]

height_ratio, width_ratio = original_height / resized_height, original_width / resized_width

# Tim kiem khuon mat bang HOG

face_locations = face_recognition.face_locations(l, model='hog')

# Neu tim thay it nhat 1 khuon mat if len(face_locations):

# Lay vi tri khuon mat

top, right, bottom, left = face_locations[0] x1, y1, x2, y2 = left, top, right, bottom x1 = int(x1 * width_ratio)

y1 = int(y1 * height_ratio) x2 = int(x2 * width_ratio) y2 = int(y2 * height_ratio) #self.find_faces = True # Trich xuat vi tri 2 mat

gray = cv2.cvtColor(self.frame_in, cv2.COLOR_BGR2GRAY)

shape = sleep_predictor(gray, dlib.rectangle(x1, y1, x2, y2)) face_landmarks = face_utils.shape_to_np(shape) left_eye_indices = face_landmarks[FacialLandMarksPosition.left_eye_start_index: FacialLandMarksPosition.left_eye_end_index] (x, y, w, h) = cv2.boundingRect(np.array([left_eye_indices])) left_eye = gray[y:y + h, x:x + w]

142 right_eye_indices = face_landmarks[FacialLandMarksPosition.right_eye_start_index: FacialLandMarksPosition.right_eye_end_index] (x, y, w, h) = cv2.boundingRect(np.array([right_eye_indices])) right_eye = gray[y:y + h, x:x + w]

# Dung mobilenet de xem tung mat la MO hay DONG

left_eye_open = 'yes' if self.predict_eye_state(model=model_hdf5, image=left_eye) else 'no'

right_eye_open = 'yes' if self.predict_eye_state(model=model_hdf5, image=right_eye) else 'no'

# Neu 2 mat dong thi hien thi mau do con khong thi mau xanh if left_eye_open == 'no' and right_eye_open == 'no':

cv2.rectangle(self.frame_out, (x1, y1), (x2, y2), (0, 0, 255), 2) # turn off view

self.curr_state_list += [1] self.count_eye_close +=1 else:

cv2.rectangle(self.frame_out, (x1, y1), (x2, y2), (0, 255, 0), 2) # turn off view

self.curr_state_list += [0] self.count_eye_close = 0

self.find_face = True # Đánh dấu: tìm ra khn mặt else:

self.find_face = False #Đánh dấu: khong tìm ra khn mặt datetime_now = datetime.now()

143 delta = datetime_now - self.before_time if delta.seconds >=1:

self.before_time = datetime_now

if len(self.curr_state_list) and sum(self.curr_state_list) / len(self.curr_state_list) >0.5: self.curr_state = 1 else: self.curr_state_list = [] self.curr_state = 0

if self.waring_time > 0: # Kiem tra thoi gian tat thong bao self.waring_time -=1

if self.waring_time == 0: self.turn_off_waring()

datetime_now = datetime.now() delta_1 = datetime_now - self.before_time_1

if self.find_face and delta_1.seconds >= 1:# Th1: tim ra khuon Dấu hiệu người lái xe nhắm mắt

if self.curr_state == 0: #mo mat thi tat thong bao self.before_time_1 = datetime_now

if self.curr_warning_type == 1:#Neu la truong hop 1 thi tat canh bao self.curr_warning_time = 0

self.message_warning = False #xoa thong diep tren man hinh else:

if delta_1.seconds >= 12: #Lan3: vượt quá 12 giây

if self.curr_warning_type == 1 and self.curr_warning_time != 3:#bo self.turn_on_waring(1,3)

144

if delta_1.seconds >= 7:#Lan2: Khi người lái xe nhắm mắt từ 7 giây trở lên

if self.curr_warning_type == 1 and self.curr_warning_time != 2: self.turn_on_waring(1,2)

else:

if delta_1.seconds >= 3:#Lan1: Dấu hiệu người lái xe nhắm mắt 3 giây trở lên

self.turn_on_waring(1,1) datetime_now = datetime.now()

delta_2 = datetime_now - self.before_time_2 if delta_2.seconds >= 1:#bo qua

if self.find_face: # tim ra khuon #Th2: Các trường hợp mất nhận diện người lái xe

self.before_time_2 = datetime_now #luu thoi gian hien tai

if self.curr_warning_type == 2: #Neu la truong hop 2 thi tat canh bao self.curr_warning_time = 0

self.message_warning = False #xoa thong diep tren man hinh else:

if delta_2.seconds > 12: # Nếu thời gian cảnh báo nhắc nhở ban đầu vượt quá 10 giây

if self.curr_warning_type == 2 and self.curr_warning_time != 3: self.turn_on_waring(2,3)

self.curr_warning_time = 0

elif delta_2.seconds >= 7: # Khi không nhận diện được khuôn mặt người lái xe trong 5 giây

if self.curr_warning_type == 2 and self.curr_warning_time != 2: self.turn_on_waring(2,2)

elif delta_2.seconds >= 3: # Khi không nhận diện được khuôn mặt người lái xe trong 3 giây

145 self.turn_on_waring(2,1)

def show_message_warning(self): #Hien Thong bao len

if self.message_warning: tsize = 1

text_color = (5, 5, 255)

cv2.putText(self.frame_out, self.message_warning, (100, 350), cv2.FONT_HERSHEY_PLAIN, tsize, text_color)

#Tat canh bao

def turn_off_waring(self): mixer.music.stop() GPIO.output(21, 0)

#Chay canh bao

def turn_on_waring(self, warning_type = 0, time = 1):

message = waring_config[warning_type - 1][time - 1].get('message',False) waring_time = waring_config[warning_type - 1][time -

1].get('waring_time',False)

on_type = waring_config[warning_type - 1][time - 1].get('on_type',False) sound_name = waring_config[warning_type - 1][time -

1].get('sound_name',False) self.curr_warning_type = warning_type if self.curr_warning_time != time: self.message_warning = message self.turn_off_waring() self.curr_warning_time = time self.waring_time = waring_time

146 #Bat Relay

if on_type == 'relay_1': GPIO.output(21, 1) elif on_type == 'relay_2': GPIO.output(21, 1) elif on_type == 'relay_3': GPIO.output(21, 1) #Bat am thanh theo ten if sound_name:

mixer.music.load(sound_name) mixer.music.play()

147

PHỤ LỤC 1.1 Trích xuất nhận diện khn mặt

image = cv2.resize(image, (20, 10)) // Thay đổi kích thước ảnh thô image = image.astype(dtype=np.float32)

image_batch = np.reshape(image, (1, 10, 20, 1))

image_batch = keras.applications.mobilenet.preprocess_input(image_batch) return np.argmax(model.predict(image_batch)[0]) // Chuyển dữ liệu vè hệ

Tensor.

def run_sleep(self, cam): // Để dự đoán các hành vi ta đặt tên hàm là

“run_sleep”.

image = cv2.cvtColor(self.frame_in, cv2.COLOR_BGR2RGB) // Chuyển đổi

sang hệ màu RGB.

original_height, original_width = image.shape[:2]

resized_image = cv2.resize(image, (0, 0), fx=self.sleep_scale, fy=self.sleep_scale)

lab = cv2.cvtColor(resized_image, cv2.COLOR_BGR2LAB) l, _, _ = cv2.split(lab)

resized_height, resized_width = l.shape[:2]

height_ratio, width_ratio = original_height / resized_height, original_width / resized_width // Chuyển sang hệ màu L*a*b* để lấy các mốc điểm chiều cao và

chiều rộng.

face_locations = face_recognition.face_locations(l, model='hog') // Tìm kiếm

khn mặt bằng HOG.

148

top, right, bottom, left = face_locations[0] // Trích xuất vị trí, vẽ khung

nhận diện khuôn mặt.

x1, y1, x2, y2 = left, top, right, bottom x1 = int(x1 * width_ratio)

y1 = int(y1 * height_ratio) x2 = int(x2 * width_ratio) y2 = int(y2 * height_ratio)

PHỤ LỤC 1.2 Xác định vị trí mắt và trích xuất trạng thái mắt đóng/mở

gray = cv2.cvtColor(self.frame_in, cv2.COLOR_BGR2GRAY) //Trích xuất

vị trí 2 mắt.

shape = sleep_predictor(gray, dlib.rectangle(x1, y1, x2, y2)) face_landmarks = face_utils.shape_to_np(shape) left_eye_indices = face_landmarks[FacialLandMarksPosition.left_eye_start_index: FacialLandMarksPosition.left_eye_end_index] (x, y, w, h) = cv2.boundingRect(np.array([left_eye_indices])) left_eye = gray[y:y + h, x:x + w] right_eye_indices = face_landmarks[FacialLandMarksPosition.right_eye_start_index: FacialLandMarksPosition.right_eye_end_index] (x, y, w, h) = cv2.boundingRect(np.array([right_eye_indices])) right_eye = gray[y:y + h, x:x + w]

149

left_eye_open = 'yes' if self.predict_eye_state(model=model_hdf5, image=left_eye) else 'no' //Dùng Mobilnet để kiểm tra mắt đóng hay mắt mở. right_eye_open = 'yes' if self.predict_eye_state(model=model_hdf5, image=right_eye) else 'no'

self.find_face = True // Đánh dấu: nhận diện được khuôn mặt. else:

self.find_face = False // Đánh dấu: không nhận diện được khuôn mặt

PHỤ LỤC 1.3 Cách thức trích xuất nhịp tim bằng OpenCV trong Python

(Tham khảo: Tristan Hearn, “using only their own webcam”, ngày 27 tháng 6 năm 2017 <https://github.com/thearn/webcam-pulse-detector>).

ef resource_path(relative_path):

""" Get absolute path to resource, works for dev and for PyInstaller """

Một phần của tài liệu Ứng dụng xử lý ảnh trong nhận diện điều khiển ô tô (Trang 137 - 181)

Tải bản đầy đủ (PDF)

(181 trang)