1. Trang chủ
  2. » Luận Văn - Báo Cáo

Ứng dụng xử lý ảnh trong nhận diện điều khiển ô tô

186 0 0

Đang tải... (xem toàn văn)

Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống

THÔNG TIN TÀI LIỆU

BỘ GIÁO DỤC VÀ ĐÀO TẠO TRƯỜNG ĐẠI HỌC CÔNG NGHỆ TP HỒ CHÍ MINH ĐỒ ÁN TỐT NGHIỆP ỨNG DỤNG XỬ LÝ ẢNH TRONG NHẬN DIỆN ĐIỀU KHIỂN Ô TÔ NGÀNH: CÔNG NGHỆ KỸ THUẬT Ô TÔ GIẢNG VIÊN HƯỚNG DẪN: TS NGUYỄN PHỤ THƯỢNG LƯU Sinh viên thực hiện: MSSV: Lớp: Trần Đình Hiếu 1711250341 17DOTB2 Phạm Xuân Phong 1711250619 17DOTB2 Phạm Chánh Tân 1711250443 17DOTB2 Tp Hồ Chí Minh, tháng 09, năm 2021 LỜI CAM ĐOAN Nhóm chúng em xin cam đoan cơng trình nghiên cứu nhóm em thực hướng dẫn Thầy TS Nguyễn Phụ Thượng Lưu Các số liệu sử dụng phân tích luận văn có nguồn gốc rõ ràng, công bố theo quy định Các kết nghiên cứu luận văn nhóm em tự tìm hiểu, phân tích cách trung thực, khách quan phù hợp với thực tiễn Việt Nam Các kết chưa công bố cơng trình khác Nếu có gian lận nào, nhóm em xin chịu trách nhiệm trước Hội đồng kết luận văn Tp Hồ Chí Minh, ngày 25 tháng 08 năm 2021 (Ký tên ghi rõ họ tên) i LỜI CẢM ƠN Lời đầu tiên, chúng em xin cảm ơn Ban Giám Hiệu Trường Đại Học Công Nghệ TP.HCM tạo điều kiện, sở vật chất để nhóm em thực đồ án Tiếp theo, chúng em xin chân thành cảm ơn quý thầy cô ngành Công Nghệ Kỹ Thuật Ơ tơ nỗ lực truyền đạt kiến thức suốt trình chúng em học tập trường nhiệt tình giúp đỡ nhóm em suốt q trình nghiên cứu hồn thành đề tài giao Cuối cùng, chúng em sâu sắc bày tỏ lòng tri ân đến Thầy TS Nguyễn Phụ Thượng Lưu giúp đỡ nhiệt tình nhóm suốt q trình nghiên cứu đến hồn thành đề tài “Ứng dụng xử lý ảnh nhận diện điều khiển ô tô” Mặc dù chúng em cố gắng nhiều với vốn kiến thức kinh nghiệm thực tế hạn hẹp, báo cáo nhóm em khơng tránh khỏi có sai lầm, thiếu sót Chúng em mong nhận dạy, lời khun, đóng góp vơ q báu q Thầy Cơ để nhóm hồn thiện tốt Một lần nữa, nhóm nghiên cứu xin chân thành cảm ơn! ii MỤC LỤC LỜI CAM ĐOAN i LỜI CẢM ƠN ii MỤC LỤC iii DANH MỤC CÁC TỪ VIẾT TẮT ix DANH MỤC CÁC HÌNH x LỜI MỞ ĐẦU xv Chương .1 GIỚI THIỆU ĐỀ TÀI 1.1 Tính cấp thiết đề tài 1.1.1 Đặt vấn đề 1.1.2 Tầm quan trọng đề tài 1.1.3 Ý nghĩa đề tài 1.1.4 Lý chọn đề tài 1.2 Tình hình nghiên cứu 1.3 Mục đích nghiên cứu 1.4 Nhiệm vụ nghiên cứu 1.5 Phương pháp nghiên cứu 1.6 Kết đạt đề tài .7 1.7 Kết cấu đề tài .7 Chương .8 TỔNG QUAN GIẢI PHÁP 2.1 Tự nhận thức lái xe iii 2.2 Giáo dục nhận thức cho người lái xe 2.2.1 Dấu hiệu cảnh báo người lái mệt mỏi 2.2.2 Một số phòng tránh mệt mỏi lái xe 2.3 Sử dụng thiết bị hỗ trợ .10 2.3.1 Dòng thiết bị đơn giản 11 2.3.2 Dòng thiết bị cao cấp 11 2.4 Xây dựng mơ hình ứng dụng thiết bị 11 2.4.1 Ngôn ngữ lập trình Python .11 2.4.2 Đặc điểm, ứng dụng OpenCV 13 2.4.3 Raspberry Pi Model B 13 Chương 15 PHƯƠNG PHÁP GIẢI QUYẾT .15 3.1 Nhận diện phát dấu hiệu mệt mỏi người lái xe 15 3.1.1 Một số vấn đề cần giải 17 3.1.2 Sử dụng trắc nghiệm nhanh xác định trạng thái tỉnh táo người lái xe 19 3.2 Xử lý thông tin theo mức độ mệt mỏi người lái xe 19 3.3 Cách thức nhận diện tạo tín hiệu cảnh báo 21 3.3.1 Thu nhận hình ảnh tiền xử lý 21 3.3.2 Nhận diện 22 3.3.3 Cảnh báo 24 3.4 Tín hiệu kích thích 26 3.5 Các loại tín hiệu kích thích sử dụng để cảnh báo thiết bị 28 3.5.1 Kích thích ánh sáng 28 iv 3.5.2 Kích thích âm 29 Chương 30 THIẾT KẾ CHẾ TẠO MƠ HÌNH 30 4.1 Nghiên cứu tổng quan .30 4.1.1 Phân tích số thiết bị có chức tương tự 30 4.1.1.1 Thiết bị cảnh bảo buồn ngủ Carcam Fatigue Warning System .30 4.1.1.2 Thiết bị cảnh báo ngủ gật lái xe tích hợp GPS FW-03 32 4.1.1.3 Thiết bị hỗ trợ theo dõi nhịp tim dùng tơ 34 4.1.1.4 Dịng thiết bị đơn giản cảnh báo buồn ngủ cho người lái xe 36 4.1.1.5 Dòng thiết bị cao cấp thiết kế theo nhà sản xuất (Ford) .38 4.1.2 Nghiên cứu thực xử lý ảnh 39 4.1.2.1 Tiền xử lý ảnh 39 4.1.2.2 Các mốc khuôn mặt ứng dụng OpenCV Python 45 4.2 Phân tích thiết kế mơ hình 47 4.2.1 Yêu cầu thiết kế 48 4.2.1.1 Phần cứng 48 4.2.1.2 Phần mềm 49 4.2.2 Sơ đồ khối tổng quan 51 4.2.3 Nguyên lý hoạt động 52 4.3 Thiết kế xây dựng mơ hình thiết bị 54 4.3.1 Sơ đồ cấu tạo 54 4.3.2 Bản vẽ chi tiết có kích thước phận mơ hình 56 4.3.3 Cấu tạo phần cứng mơ hình 65 4.3.3.1 Mạch Raspberry Pi Model B (8GB) 65 v self.before_time_3 = datetime.now() self.message_warning = False self.curr_warning_type = self.curr_warning_time = self.waring_time = self.estimate = 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 152 def draw_rect(self, rect, col=(0, 255, 0)): 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) / def train(self): self.trained = not self.trained 153 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() 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): 154 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), 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] 155 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) > and len(processed) > 0: while len(self.times) != len(processed): if len(self.times) > len(processed): self.times.pop() else: processed.pop() 156 self.samples = processed 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 / + < len(self.fft) and L / + 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 157 self.fft = pruned idx2 = np.argmax(pruned) t = (np.sin(phase[idx2]) + 1.) / t = 0.9 * t + 0.1 alpha = t beta = - t self.bpm = self.freqs[idx2] + self.estimate self.idx += 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: 158 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 = 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 PHỤ LỤC 1.4 Kiểm tra, xử lý thông tin trường hợp đưa định cảnh báo // swaring_time: thời gian cảnh báo // on_type: chọn relay bật // sound_name: âm sử dụng đưa cảnh báo if self.waring_time > 0: // Kiểm tra thời gian tắt thông báo self.waring_time -=1 if self.waring_time == 0: self.turn_off_waring() datetime_now = datetime.now() 159 delta_1 = datetime_now - self.before_time_1 if self.find_face and delta_1.seconds >= 1: // Trường hợp mở mắt tắt thơng báo, với “0” mở mắt if self.curr_state == 0: self.before_time_1 = datetime_now // Nếu trường hợp tắt cảnh báo if self.curr_warning_type == 1: self.curr_warning_time = self.message_warning = False else: if delta_1.seconds >= 12: if self.curr_warning_type == and self.curr_warning_time != 3: self.turn_on_waring(1,3) // Thời gian nhắm mắt lớn 12 giây đưa cảnh báo, ngược lại tiếp tục kiểm tra Trường hợp 1.2 (Th_1.2): Nếu thời gian lớn giây đưa cảnh báo, ngược lại tiếp tục kiểm tra “Th_1.3” else: if delta_1.seconds >= 7: if self.curr_warning_type == and self.curr_warning_time != 2: self.turn_on_waring(1,2) // Thời gian nhắm mắt lớn 7giây đưa cảnh báo, ngược lại tiếp tục kiểm tra else: if delta_1.seconds >= 3: 160 self.turn_on_waring(1,1) // Thời gian nhắm mắt lớn giây đưa cảnh báo, ngược lại quay lại tiếp tục kiểm tra if self.find_face: self.before_time_2 = datetime_now // Tìm khn mặt người lái xe lưu trữ thời gian if self.curr_warning_type == 2: self.curr_warning_time = self.message_warning = False else: if delta_2.seconds > 12: if self.curr_warning_type == and self.curr_warning_time != 3: self.turn_on_waring(2,3) self.curr_warning_time = //Thời gian nhận diện lớn 12 giây đưa cảnh báo, ngược lại tiếp tục kiểm tra elif delta_2.seconds >= 7: if self.curr_warning_type == and self.curr_warning_time != 2: self.turn_on_waring(2,2) //Thời gian nhận diện lớn giây đưa cảnh báo, ngược lại tiếp tục kiểm tra elif delta_2.seconds >= 3: self.turn_on_waring(2,1) //Thời gian nhận diện lớn giây đưa cảnh báo, ngược lại tiếp tục kiểm tra if self.find_face: # tim khuon if bpm >= 50 and bpm 12: if self.curr_warning_type == and self.curr_warning_time != 3: self.turn_on_waring(3,3) self.curr_warning_time = // Nếu thời gian nhịp tim 100 bpm lớn 12 giây đưa cảnh báo, ngược lại không cảnh báo, tiếp tục kiểm tra elif delta_3.seconds >= 7: if self.curr_warning_type == and self.curr_warning_time != 2: self.turn_on_waring(3,2) // Nếu lớn giây đưa cảnh báo, ngược lại tắt cảnh báo, tiếp tục kiểm tra elif delta_3.seconds >= 3: self.turn_on_waring(3,1) // Nếu lớn giây đưa cảnh báo, ngược lại tắt cảnh báo, tiếp tục kiểm tra def turn_off_waring(self): 162 mixer.music.stop() GPIO.output(21, 0) //Tắt cảnh báo 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) //Cấu hình bật relay mạch if sound_name: mixer.music.load(sound_name) mixer.music.play() //Âm cảnh báo bật theo tệp 163 PHỤ LỤC 1.5 Tiếp nhận đưa cảnh báo waring_config = [ [ { "message": "Nguoi lai xe nham mat hon giay", "waring_time": 2, "on_type": 0, "sound_name": 'sound/th1_1.mp3' // Cảnh báo trường hợp 1.1 (Th_1.1) },{ "message": "Nguoi lai xe nham mat hon giay", "waring_time": 2, "on_type": 0, "sound_name": 'sound/th1_2.mp3' // Cảnh báo trường hợp 1.2 (Th_1.2) },{ "message": "Nguoi lai xe nham mat hon 12 giay", "waring_time": 4, "on_type": 'relay_1', "sound_name": 'sound/th1_3.mp3' // Cảnh báo trường hợp 1.3 (Th_1.3) } ], 164 [ { "message": "Khong tim thay khuon mat 3s", "waring_time": 2, "on_type": 0, "sound_name": 'sound/th2_1.mp3' // Cảnh báo trường hợp 2.1 (Th_2.1) },{ "message": "Khong tim thay khuon mat 7s", "waring_time": 2, "on_type": 0, "sound_name": 'sound/th2_2.mp3' // Cảnh báo trường hợp 2.2 (Th_2.2) },{ "message": "Khong tim thay khuon mat vuot qua 12s", "waring_time": 4, "on_type": 'relay_1', "sound_name": 'sound/th2_3.mp3' // Cảnh báo trường hợp 2.3 (Th_2.3) } ], 165 [ { "message": "Nhip tim vuot qua nguong 50-100 3s", "waring_time": 2, "on_type": 0, "sound_name": 'sound/th3_1.mp3' // Cảnh báo trường hợp 3.1 (Th_3.1) },{ "message": "Nhip tim vuot qua nguong 50-100 7s", "waring_time": 3, "on_type": 0, "sound_name": 'sound/th3_2.mp3' // Cảnh báo trường hợp 3.3 (Th_3.2) },{ "message": "Nhip tim vuot qua nguong 50-100 qua 12s", "waring_time": 4, "on_type": 'relay_1', "sound_name": 'sound/th3_3.mp3' // Cảnh báo trường hợp 3.3 (Th_3.3) } ], 166

Ngày đăng: 31/08/2023, 08:56

Xem thêm:

TÀI LIỆU CÙNG NGƯỜI DÙNG

TÀI LIỆU LIÊN QUAN

w