CHƯƠNG 4 THI CÔNG HỆ THỐNG
4.1 LƯU ĐỒ GIẢI THUẬT
4.1.4 Vẽ hình chữ nhật xung quanh khuôn mặt
Hàm detectMultiScale sau khi tìm kiếm xong sẽ trả về bộ gái trị gồm tọa độ gốc của khung hình chứa khuôn mặt x, y; chiều dài, chiều rộng của khung w, h. Các
giá trị này nằm trong mảng faces. Cấu trúc for…in sẽ duyệt qua toàn bộ giá trị này, mỗi bộ giá trị ta dùng hàm rectangle để vẽ 1 hình chữ nhật lên ảnh ban đầu với tọa độ 2 điểm trái trên và phải dưới: (x,y), (x+w, y+h). Thông số (0,255,0) là màu vẽ của khung hình chữ nhật.
Hình 4.4. Ảnh được vẽ hình chữ nhật lên khuôn mặt. 4.1.5. Đếm số lượng khuôn mặt 4.1.5. Đếm số lượng khuôn mặt
Sau khi vẽ hình chữ nhật xung quanh khuôn mặt xong, nhóm gọi phương thức
shape sẽ được trả về kích thước của khuôn mặt bao gồm 1 ma trận có N hàng và 4
cột. Trong đó, N là số lượng khuôn mặt được phát hiện trong ảnh và 4 là kích thước của hình chữ nhật của mỗi mặt.
4.1.6. Xuất kết quả ra màng hình
Dùng hàm cv2.imshow('Ket qua', image) để hiển thị ảnh đã vẽ xong lên 1
cửa sổ windown có tên là Ket qua.
Hình 4.5. Kết quả được xuất ra cửa sổ windown
4.2 Kết quả
Hình 4.7. Kết quả sau khi chạy chương trình
Hình 4.7 là kết quả của quá trình đếm số lượng người trong ảnh. Trên hình ảnh, chúng ta có thể thấy rằng những khuôn mặt xuất hiện trong ảnh đều được vẽ hình chữ nhật. Sau khi được xử lý và đếm số lượng kết quả được xuất ra trên màng hình.
Chương 5. KẾT QUẢ_NHẬN XÉT_ĐÁNH GIÁ
Nhóm bắt đầu nhận đề tài “Đếm số lượng người trong ảnh sử dụng kit
Raspberry Pi” từ ngày 26/08/2019. Bắt đầu nghiên cứu và thực hiện đề tài trong vòng
17 tuần để hoàn thành hệ thống. Trong quá trình nghiên cứu và thực hành nhóm đã học và rút ra được nhiều kinh nghiệm như: biết cách tìm hiểu nghiên cứu về một vấn đề, hiểu và biết sử dụng LCD, chuẩn truyền I2C. Biết thêm về tính năng của Raspberry Pi, cách cài đặt kết nối với các Module và hiểu thêm về ngôn ngữ Python.
Trong quá trình nhóm nghiên cứu đã thu được rất nhiều kết quả để chứng minh cho những cơ sở lý thuyết, những tính toán thiết kế và thi công của mình đi đúng hướng. Kết quả thực hiện nhóm đã hoàn thành được để tài. Bây giờ hệ thống có thể đếm được số lượng người trong hình. Thời gian đáp ứng để thực hiện đếm của hệ thống trong một lần đếm là khoảng 10 giây. Hệ thống dễ dàng sử dụng và an toàn.
5.1. KẾT QUẢ
Hình 5.1. Kết quả chương trình
Hình 5.1 là kết quả của chương trình đếm số lượng người trong ảnh. Trong quá trình tìm kiếm khuôn mặt chương trình sẽ tìm được nhiều những khung hình chữ nhật chứa khuôn mặt cho dù đó chỉ là một khuôn mặt và có những trường trường hợp
Hình 5.2. Kết quả chương trình đếm nhầm số lượng
Hình 5.2 chương trình đã nhận diện nhằm túi áo của bạn nam sinh là khuôn mặt (bạn nam thứ 2 từ trái sang phải và từ trên xuống dưới) dẫn đến kết quả đếm sai so với số lượng người thực tế có trong ảnh.
Nếu ta để tham số minNeighbor = 0 cho hàm tìm kiếm khuôn mặt, tức là để
nguyên những gì tìm được sau khi quét thì sẽ có kết quả như sau:
Kết quả đếm số lượng người trong trường hợp này lớn hơn rất nhiều so với kết quả thực tế (thực tế trong ảnh chỉ có 11 người nhưng chương trình xuất ra kết quả là 300 người).
Từ kết quả của hình 5.3 cho ta thấy tham số này sẽ gộp lại những khung hình chữ nhật chứa cùng 1 khuôn mặt để chỉ cho ra 1 hình chữ nhật cho 1 khuôn mặt. Đồng thời nó sẽ loại bỏ đi những kết quả sai vì những kết quả chỉ cho ra 1 khung hình chữ nhật con kết quả đúng thì có nhiều khung hình lân cận bao lấy.
Hình 5.4. Kết quả đếm sai khi minNeighbor = 5
Khi chọn tham số minNeighbor = 5 trong trường hợp hình 5.4 thì cho ra kết quả sai với số lượng thực tế. Vì những hình chữ nhật lân cận đã được gộp lại sau khi quá trình quét xong. Để cho kết quả đúng với thực tế ta cần chỉnh sửa tham số minNeighbor = 2 dựa vào chạy thử nghiệm chương trình nhiều lần.
Hình 5.5. Kết quả đếm đúng khi minNeighbor = 2
Hình 5.6. Kết quả đếm số lượng người trong ảnh với khuôn mặt nghiêng
Nhìn vào hình 5.5 ta có thể thấy hệ thống có thể đếm được số lượng khi khuôn mặt nghiêng hoặc bị che khuất khoảng 10-20% khuôn mặt. Để có kết quả đếm chính xác nhóm đã chạy thử nghiệm nhiều lần và đã chọn được thông số minNeighbor = 2 , scaleFactor = 1.3 để chương trình có thể quét nhiều lần hơn tránh bỏ sót. Tuy nhiên, thời gian xử lý sẽ chậm hơn so với những ảnh thông thường.
Hình 5.7. Kết quả đếm khi không có người trong ảnh
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)