Hình 5.7 là kết quả đếm khi không có người xuất hiện trong ảnh. Bên cạnh đó nếu như trong ảnh có người mà không có xuất hiện khuôn mặt (người trong ảnh lúc này quay lưng lại hoặc khuôn mặt nghiêng hơn 30%).
5.2. Nhận xét
Để đánh giá, nhận xét một cách thực tế, nhóm đã chạy thử nghiệm trên những ảnh có mật độ người trong ảnh cao và thấp hoặc trong ảnh có khuôn mặt nghiêng. Kết quả được thể hiện ở bảng 5.1 và 5.2:
Bảng 5.1. Thống kê kết quả đếm số người trong ảnh khi khuôn mặt chính diện STT Số lượng thực tế Kết quả đếm từ hệ STT Số lượng thực tế Kết quả đếm từ hệ thống Sai số 1 1 1 0 2 4 4 0 3 5 5 0 4 8 8 0 5 10 10 0 6 15 15 0 7 23 21 2 8 27 28 1 9 30 28 2 10 39 38 1
Từ những hình ảnh kết quả chạy thử nghiệm và được thống kê trong bảng 5.1 cho thấy hệ thống khá ổn định, độ chính xác tương đối cao.
Bảng 5.2. Thống kê kết quả đếm số người trong ảnh khi khuôn mặt nghiêng STT Số lượng
thực tế
Số lượng đếm được Sai số
< =25% > 25% < =25% > 25% 1 1 1 0 0 1 2 3 3 1 0 2 3 6 5 9 1 3 4 8 8 5 0 3 5 10 10 6 0 4
Theo kết quả chạy thử nghiệm và thống kế trong bảng 5.2 cho thấy hệ thống đếm ổn định, sai số thấp có thể chấp nhận được khi khuôn mặt trong hình nghiêng nhỏ hơn
25%. Khi khuôn mặt trong hình nghiêng lớn hơn 25% hệ thống sẽ không nhận diện được khuôn mặt dẫn đến hệ thống đếm sai số lượng người có trong hình.
Tuy nhiên, nhóm vẫn chỉ dừng lại ở mức mô hình. Nếu như mô hình này khi được khai thác thì sẽ ứng dụng rất nhiều trong việc điểm danh trong lớp học hay chấm công trong công ty. Việc khai thác mô hình này trong thực tiễn thì phải tốn thêm nhiều thời gian và chi phí để thực hiện.
Chương 6. KẾT LUẬN VÀ HƯỚNG PHÁT TRIỂN
6.1 KẾT LUẬN
Mục tiêu chính của đề tài là đếm được số lượng người trong ảnh. Sau quá trình thực hiện thì hệ thống đã có thể đếm được số lượng người trong ảnh tương đối chính xác với sai số nhỏ khi trong ảnh có xuất hiện mặt người hoặc khi khuôn mặt nghiêng từ 10 – 25%.
Qua thời gian nghiên cứu và thực hiện thì nhóm chỉ dừng lại ở mức mô hình sản phẩm để thử nghiệm và không thể đếm với số lượng người trong ảnh khi mặt bị che khuất hoặc chỉ thấy từ đằng sau người đó. Mặc dù đã cố gắng nhưng do giới hạn về thời gian thực hiện và năng lực còn yếu nên nhóm không thể hoàn toàn khắc phục được hạn chế của sản phẩm.
Trong suốt quãng thời gian nghiên cứu đồ án, nhóm chúng em cũng đã học được khá nhiều điều như học được cách đương đầu với áp lực, cách nghiên cứu về một vấn đề, khả năng phân chia công việc và lên kế hoạch, nhất là đức tính kiên trì khi lập trình bị lỗi. Quả thực, môi trường Đại Học Sư Phạm Kỹ Thuật là rất tốt trong việc rèn luyện nhân cách, phương pháp học tập, kinh nghiệm sống của chúng mỗi người. Những điều đó làm nền tảng cho việc phát triển của mỗi cá nhân trong nhóm sau này.
6.2 HƯỚNG PHÁT TRIỂN
Dựa vào những kiến thức được tham khảo và học hỏi. Nhóm nghiên cứu nghĩ rằng đề tài này có thể phát triển và mở rộng thêm ở một số khía cạnh sau:
Có thể đếm được đối tượng khi không có xuất hiện khuôn mặt trong ảnh hoặc khuôn mặt nghiêng hơn 30%.
Nghiên cứu cải tiến những giải thuật phát hiện, nhận diện hiệu quả, chính xác và tốiưu hơn.
TÀI LIỆU THAM KHẢO
[1] Nguyễn Thanh Hải, “Giáo Trình: Xử Lý Ảnh”, Xuất bản Đại Học Quốc Gia TP.HCM, 2013.
[2] Trần Hải Đăng, “Giao tiếp I2C với nhiều module”, 2016.
[3] Đào Văn Hậu, “Nhận diện khuôn mặt với OpenCV trên Raspberry Pi”, 2019.
[4] “Raspbian Stretch: Install OpenCV 3 + Python on your Raspberry Pi” https://www.pyimagesearch.com/2017/09/04/raspbian-stretch-install-opencv-3- python-on-your-raspberry-pi/
[5] Raspberry Pi Việt Nam, “Raspberry Pi là gì? Giới thiệu về Raspberry Pi”, 2014.
https://raspberrypi.vn/tin-tuc/raspberry-pi-la-gi-gioi-thieu-ve-raspberry-pi-261.pi
[6] Nitin Patil, “How to install OpenCV on Raspberry Pi and do Face Tracking”, 2017. [7] Antepher, “Python OpenCV: Face detection and counting”, 2017.
https://techtutorialsx.com/2017/05/02/python-opencv-face-detection-and-counting/
[8] Minh Nguyễn, “Xử lý ảnh - OpenCV resize, crop và padding hình ảnh (code Python và C++) ”, 2018.
[9] Stack Overflow, “ Count the number of objects OpenCV – Python”, 2017.
https://stackoverflow.com/questions/39261378/count-the-number-of-objects-opencv- python
[10] Team Việt Dev, “OpenCV là gi, ứng dụng trong thế giới thực”, 2018.
[11] Võ Lê Huy, “OpenCV với Python Trong Ứng Dụng Phát Hiện Khuôn Mặt Trong Bức Ảnh”, 2018.
[12] Nông Văn Tâm và Trần Thị Mỹ Khiêm, “Ứng dụng xử lý ảnh vào việc phát hiện ngủ gật dùng Kit Raspberry”, 2019.
[13] Võ Sĩ Nguyên, “Thiết kế và thi công hệ thống đếm số lượng cá giống”, 2019. [13] Dương Nguyễn, “Python là gì? Tại sao nên chọn python?”, 2019.
https://quantrimang.com/python-la-gi-tai-sao-nen-chon-python-140518
[14] Tuấn Nguyễn, “Hiển thị dữ liệu từ Raspberry Pi lên LCD16x2 qua mạch chuyển tiếp LCM1602”, 2017.
[15] “Adaboost - Haar Features - Face detection” [Online]. Available: http://www.ieev.org/2010/03/adaboost-haar-features-face-detection_22.html
PHỤ LỤC
#khai bao thu vien import numpy as np import cv2
import smbus import time
I2C_ADDR = 0x3f # dung lenh sudo i2cdetect -y 1 ban se thay dia chi cua module lcd la 0x3f
LCD_WIDTH = 16 # so ki tu tren 1 dong
LCD_CHR = 1 # Gui ki tu LCD_CMD = 0 # Gui lenh
LCD_LINE_1 = 0x80 # dia chi RAM dong 1 LCD_LINE_2 = 0xC0 # dia chi RAM dong 2
LCD_BACKLIGHT = 0x08 # On #LCD_BACKLIGHT = 0x00 # Off
ENABLE = 0b00000100 # Enable bit
# delay
E_PULSE = 0.0005 E_DELAY = 0.0005
#bus = smbus.SMBus(0) # Pi Rev 1 ban su dung dong nay bus = smbus.SMBus(1) # Pi Rev 2 ban su dung dong nay
def lcd_init(): # Initialise display
lcd_byte(0x33,LCD_CMD) # che do 8 bits
lcd_byte(0x32,LCD_CMD) # che do 8 bits lan nua
lcd_byte(0x06,LCD_CMD) # che do 4 bits, LCD hien thi 2 dong lcd_byte(0x0C,LCD_CMD) # xoa hien thi
lcd_byte(0x28,LCD_CMD) # con tro tu dong di chuyen
lcd_byte(0x01,LCD_CMD) # bat hien thi, tat con tro nhap nhay time.sleep(E_DELAY)
# gui 1 byte xuong LCD def lcd_byte(bits, mode):
bits_high = mode | (bits & 0xF0) | LCD_BACKLIGHT bits_low = mode | ((bits<<4) & 0xF0) | LCD_BACKLIGHT #che do 4 bits: gui byte cao truoc byte thap sau
# byte cao bus.write_byte(I2C_ADDR, bits_high) lcd_toggle_enable(bits_high) # byte thap bus.write_byte(I2C_ADDR, bits_low) lcd_toggle_enable(bits_low)
# dua chan E len cao roi thap de truyen du lieu di def lcd_toggle_enable(bits):
bus.write_byte(I2C_ADDR, (bits | ENABLE)) time.sleep(E_PULSE)
bus.write_byte(I2C_ADDR,(bits & ~ENABLE)) time.sleep(E_DELAY)
# gui chuoi ki tu xuong LCD def lcd_string(message,line): message = message.ljust(LCD_WIDTH," ") lcd_byte(line, LCD_CMD) for i in range(LCD_WIDTH): lcd_byte(ord(message[i]),LCD_CHR)
# Doc anh dau vao va tep tin xml
face_cascade = cv2.CascadeClassifier('haarcascade_frontalface_default.xml') image = cv2.imread('hinh8_nu.jpg') y=0 x=0 h=600 w=1000 crop = image[y:y+h, x:x+w]
# Tao buc anh xam
grayImage = cv2.cvtColor(crop, cv2.COLOR_BGR2GRAY)
# Tim khuon mat trong anh
faces = face_cascade.detectMultiScale(grayImage, 1.3, 2)
# Lenh re nhanh: neu khong co khuon mat xuat hien trong anh thi xuat du lieu ra la SO NGUOI : 0
if len(faces) == 0:
print ("SO NGUOI: 0" ) #xuat ket qua ra mang hinh
cv2.imshow('Image non face',crop) # xuat ket qua ra LCD
lcd_string("SO NGUOI: 0", LCD_LINE_2 ) time.sleep(3)
# cho nhan phim bat ki de thoat chuong trinh cv2.waitKey(0)
# xoa cua so hien thi cv2.destroyAllWindows()
# nguoc lai neu co nguoi xuat hien trong anh else:
# Dem so luong nguoi xuat ket qua ra mang hinh print ("SO NGUOI: " + str(faces.shape[0]))
# Ve hinh chu nhat xung quanh khuon mat voi mau xanh va do day la 2 for (x,y,w,h) in faces:
cv2.rectangle(crop,(x,y),(x+w,y+h),(255,0,0),2)
# Ve hinh chu nhat ben trai goc duoi cua anh voi mau nen la mau trang
cv2.rectangle(crop, ((0,crop.shape[0] -25)),(270, crop.shape[0]), (255,255,255), -1) # Ghi doan van ban SO NGUOI: len hinh chu nhat vua ve voi font chu la
FONT_HERSHEY_TRIPLEX va do lon cua chu la 0,5
cv2.putText(crop, " SO NGUOI: " + str(faces.shape[0]), (0,crop.shape[0] -10), cv2.FONT_HERSHEY_TRIPLEX, 0.5, (250,0,0), 1)
# xuat buc anh sau khi xu ly xong len mang hinh cv2.imshow('Image with faces',crop)
lcd_init()
# xuat ket qua ra LCD
lcd_string(" DATN ", LCD_LINE_1)
lcd_string("SO NGUOI: " + str(faces.shape[0]), LCD_LINE_2) time.sleep(3)
cv2.waitKey(0)