Trong bài này sẽ hướng dẫn các bạn nhận diện biển số xe máy. Đây là đề tài khá hấp dẫn vì mang tính thực tiễn cao, mặc dù đã nhiều người làm tuy nhiên độ chính xác chưa đạt được mức thương mại.
Để huấn luyện được Cascade thì các bạn nên đọc và hiểu hết lý thuyết trong phần 1 để dễ dàng thay đổi, tinh chỉnh các thiết lập, và cũng hiểu được các bộ dữ liệu mình chuẩn bị sẵn cho các bạn.
Nếu bạn không biết dùng command line, không biết cấu trúc của OpenCV thì bạn nên tìm hiểu trước khi đọc tiếp.
Các công cụ cần thiết
1. OpenCV 2.4.9 Đây là phiên bản ổn định (stable), các bạn có thể dùng phiên bản cao hơn vẫn ok
2. Tập dữ liệu dương: mình sử dụng bộ ảnh của công ty Green Parking. Trong file zip chứa 1749 ảnh
3. Tập dữ liệu âm: bao gồm 3000 hình ảnh bất kỳ không chứa biển số xe
4. Object locator: dùng để khoanh vùng đối tượng
5. Cascade analytics: dùng để đánh giá độ chính xác sau khi huấn luyện xong
Bắt đầu thực hiện
Các bước thực hiện như sau:
- Khoanh vùng đối tượng bằng tool Object locator
- Tạo tập ảnh sample bằng tool opencv_createsamples
- Huấn luyện bằng tool opencv_traincascade
Bước 1: Khoanh vùng đối tượng
Các bạn dùng tool Object locator vẽ hình chữ nhật bao lấy đối tượng, sau khi làm xong các bạn sẽ được file location.txt nằm trong thư mục chứa ảnh.
Mình đã tạo sẵn file location.txt cho các bạn. Và trong thư mục ảnh âm mình cũng có tạo file bg.txt chứa danh sách các file ảnh âm.
Trong thư mục ảnh âm có file _create_bg_file.bat. Các bạn chạy file đó để tạo ra file bg.txt có chứa đường dẫn tuyệt đối (để tránh lỗi tìm không thấy file)
Bước 2: Tạo tập ảnh samples
Dùng lệnh sau để tạo tập ảnh
opencv_createsamples.exe -info E:\GreenParking\location.txt -vec GreenParking.vec -w 30 -h 20 -num 1749
Ý nghĩa lệnh: bạn tạo file vecto tên là GreenParking.vec chứa 1749 ảnh crop biển số, mỗi ảnh có kích thước 30×20 pixels.
Bước 3: Huấn luyện
Tạo folder để chứa dữ liệu các bước huấn luyện, mình tạo folder E:\train
Dùng lệnh sau để huấn luyện
opencv_traincascade.exe -data E:\train -vec GreenParking.vec -bg E:\negatives\bg.txt -numPos 1700 -numNeg 3000 -w 30 -h 20 -featureType LBP
Ý nghĩa lệnh: huấn luyện để tạo file E:\train\cascade.xml, với 1700 ảnh dương và 3000 ảnh âm, với kích thước bằng kích thước samples đã được tạo, sử dụng LBP feature vì kết quả chính xác tương đương Haar feature nhưng lại nhanh hơn rất nhiều, phù hợp cho việc thử nghiệm.
Khi huấn luyện chương trình sẽ hiển thị như thế này
Lưu ý là khi tạo mẫu thì 1749 nhưng khi huấn luyện chỉ dùng 1700, điều đó giúp cho chương trình chạy không bị crash. Số lượng ảnh phải giảm đi tùy vào bộ ảnh.
Với câu lệnh như vậy mình huấn luyện trên máy CPU Intel core i5 2500 mất hơn 3 giờ
Kiểm tra độ chính xác bằng tool
Sau khi huấn luyện xong bạn sẽ được file E:\train\cascade.xml, dùng chương trình Cascade analytics để đánh giá độ chính xác. Mình đã test thử file kết quả thì độ phát hiện được 2848/3536 ảnh.
cascade.xml (22KB)
Download Cascade Analytics
Code detect object C++
1 2 3 4 5 6 7 8 9 10 11 12 |
//load file cascade đã train cv::CascadeClassifier cascade = cv::CascadeClassifier("cascade.xml"); //load ảnh và chuyển thành ảnh xám cv::Mat matGray = cv::imread("sample.jpg", cv::IMREAD_GRAYSCALE); //detect std::vector<cv::Rect> rects; cascade.detectMultiScale(matGray, rects, 1.1, 3, CV_HAAR_SCALE_IMAGE); //in ra số lượng đối tượng phát hiện được std::cout << "Detected " << rects.size() << " objects"; |
Code detect object Python
https://github.com/opencv/opencv/blob/master/samples/python/facedetect.py
thưa anh, em training xong rồi, giờ muốn sd file xml đó thì ta làm như nào ạ :))
Mình mới vừa thêm link của chương trình Cascade Analytics và source code rồi nhé bạn
em dùng đoẠN CODE C++ trên kia mà nó ko đc anh ạ
em dùng đoạn code này của python thì vẫn khoanh đc vùng biển số
import cv2
# load classifier
classifier = cv2.CascadeClassifier(‘cascade.xml’)
# load image
img = cv2.imread(‘oto.jpg’)
# convert image to grayscale
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# detect faces
faces = classifier.detectMultiScale(gray, 1.4, 3)
# draw rectangles on image for every detected face
for (x,y,w,h) in faces:
img = cv2.rectangle(img, (x,y), (x+w,y+h), (455, 0, 0), 4)
print(x, y, w, h)
cv2.imwrite(‘test_sv.jpg’, img)
cv2.imshow(‘out’, img)
cv2.waitKey(0)
cv2.destroyAllWindows()
anh ơi cho em hỏi lỗi này là gì ạ:
OpenCV Error: Insufficient memory (Failed to allocate 1073740800 bytes) in cv::OutOfMemoryError, file C:\builds\master_PackSlave-win64-vc12-shared\opencv\modules\core\src\alloc.cpp, line 52
OpenCV Error: Assertion failed (u != 0) in cv::Mat::create, file C:\builds\master_PackSlave-win64-vc12-shared\opencv\modules\core\src\matrix.cpp, line 411
Bạn kiểm tra xem có đủ RAM không
dạ em thưa anh, nếu trong trường hợp em đang train em yêu cầu 18 Stage mà nó chỉ chạy đến Stage 13 xong ra thông báo như này thì đã train thành công chưa ạ
Required leaf false alarm rate achieved. Branch training terminated.
Vậy là train thành công rồi đó bạn, vào thư mục train sẽ thấy file cascade.xml. Còn lý do không đủ stage là do bộ ảnh dương của bạn quá ít (dưới 1000)
dạ vâng. Em cảm ơn anh ạ!
anh ơi, cho em hỏi là khi em train thành công rồi nhưng khi chạy chương trình nó lại không thể load được file cascade.xml là sao ạ.Em đã chỉ rõ đường dẫn của file xml khi gọi hàm load rồi ạ.
nó báo lỗi gì bạn?
anh ơi cho em hỏi đây là lỗi gì ạ:
F:\opencv\build\x64\vc15\bin>opencv_traincascade.exe -data E:\train -vec E:\bien.vec -bg C:\Users\DELL\Desktop\hoa-anh-am\bg.txt -numPos 49 -numNeg 25 -w 30 -h 20 -featureType LBP -mode ALL
PARAMETERS:
cascadeDirName: E:\train
vecFileName: E:\bien.vec
bgFileName: C:\Users\DELL\Desktop\hoa-anh-am\bg.txt
numPos: 49
numNeg: 25
numStages: 20
precalcValBufSize[Mb] : 1024
precalcIdxBufSize[Mb] : 1024
acceptanceRatioBreakValue : -1
stageType: BOOST
featureType: LBP
sampleWidth: 30
sampleHeight: 20
boostType: GAB
minHitRate: 0.995
maxFalseAlarmRate: 0.5
weightTrimRate: 0.95
maxDepth: 1
maxWeakCount: 100
Number of unique features given windowSize [30,20] : 9135
===== TRAINING 0-stage =====
Can not get new positive sample. The most possible reason is insufficient count of samples in given vec-file.
> ) in CvCascadeImageReader::PosReader::get, file c:\build\master_winpack-build-win64-vc15\opencv\apps\traincascade\imagestorage.cpp, line 158
Mình không biết bước 1 (tạo sample) của bạn thành công không, tuy nhiên thấy số lượng ảnh của bạn quá ít, tốt nhất từ 300 trở lên
> opencv_createsamples -info E:\GreenParking\location.txt -vec GreenParking.vec -w 30 -h 20 -num 3500
em chạy câu lệnh trên nhưng bị lỗi ở tham số -num 3500, báo lỗi như sau:
>OpenCV(3.4.5) Error: Bad argument (> Can not get new positive sample. The most possible reason is insufficient count >of samples in given vec-file.
em chỉnh sửa -num thành <= 1749 (số file ảnh dương thực tế) thì chạy được, em nghĩ giá trị tham số 3500 hình như có vấn đề phải không anh?
oh thanks bạn đã chỉ ra sai sót, để mình cập nhật lại
Em bị lỗi như thế này thì sửa như thế nào ạ???
C:\opencv\build\x64\vc15\bin>opencv_traincascade -data D:\train -vec D:\GreenParking.vec -bg D:\negatives\bg.txt -numPos 1748 -numNeg 3000 -w 30 -h 20 -featureType LBP -mode ALL
———————————————————————————
Training parameters are pre-loaded from the parameter file in data folder!
Please empty this folder if you want to use a NEW set of training parameters.
———————————————————————————
PARAMETERS:
cascadeDirName: D:\train
vecFileName: D:\GreenParking.vec
bgFileName: D:\negatives\bg.txt
numPos: 1748
numNeg: 3000
numStages: 20
precalcValBufSize[Mb] : 1024
precalcIdxBufSize[Mb] : 1024
acceptanceRatioBreakValue : -1
stageType: BOOST
featureType: LBP
sampleWidth: 30
sampleHeight: 20
boostType: GAB
minHitRate: 0.995
maxFalseAlarmRate: 0.5
weightTrimRate: 0.95
maxDepth: 1
maxWeakCount: 100
Number of unique features given windowSize [30,20] : 9135
Stage 0 is loaded
===== TRAINING 1-stage =====
Can not get new positive sample. The most possible reason is insufficient count of samples in given vec-file.
> ) in CvCascadeImageReader::PosReader::get, file c:\build\3_4_winpack-build-win64-vc15\opencv\apps\traincascade\imagestorage.cpp, line 158
lỗi này do app không thấy ảnh negatives. bạn vào folder negative double click vào file .bat để tạo file bg.txt mới
mình đã làm theo bạn nhiều lần nhưng vẫn gặp lỗi này.
Bạn vào group post mã lỗi và các steps đã làm để mọi người dễ support bạn hơn: https://www.facebook.com/groups/thigiacmaytinh
Mọi người sửa lỗi này như thế nào vậy?
anh ơi em bị lỗi như thế này thì sửa như thế nào ạ???
C:\Users\Admin>C:\Users\Admin\Downloads\Programs\opencv\build\x64\vc12\bin\opencv_traincascade.exe
Usage: C:\Users\Admin\Downloads\Programs\opencv\build\x64\vc12\bin\opencv_traincascade.exe
-data
-vec
-bg
[-numPos ]
[-numNeg ]
[-numStages ]
[-precalcValBufSize ]
[-precalcIdxBufSize ]
[-baseFormatSave]
–cascadeParams–
[-stageType ]
[-featureType ]
[-w ]
[-h ]
–boostParams–
[-bt ]
[-minHitRate = 0.995>]
[-maxFalseAlarmRate ]
[-weightTrimRate ]
[-maxDepth ]
[-maxWeakCount ]
–haarFeatureParams–
[-mode C:\Users\Admin\Downloads\Programs\opencv\build\x64\vc12\bin\opencv_traincascade.exe-data D:\output -vec D:\bienso.vec -bg C:\Users\Admin\Desktop\anhsai\list.txt -numPos 15 -numNeg 13 -numStage 20 -minHitRate 0.995 -maxFalseAlarmRate 0.5 -w 134 -h 118
‘C:\Users\Admin\Downloads\Programs\opencv\build\x64\vc12\bin\opencv_traincascade.exe-data’ is not recognized as an internal or external command,
operable program or batch file.
opencv_traincascade.exe-data dính nhau nên không chạy được, bạn thêm khoảng trắng phía sau exe
e cảm ơn anh!e sử được lỗi đó rồi ạ.nhưng giờ e bị lỗi này thì sử như nào ạ??
C:\Users\Admin>C:\Users\Admin\Desktop\OPENCV\caidatopencv\build\x64\vc12\bin\opencv_traincascade.exe -data D:\train -vec bienso.vec -bg C:\Users\Admin\Desktop\ML\anhsai\list.txt -numPos 15 -numNeg 13 -w 135 -h 120 -featureType LBP -mode ALL
Training parameters are loaded from the parameter file in data folder!
Please empty the data folder if you want to use your own set of parameters.
PARAMETERS:
cascadeDirName: D:\train
vecFileName: bienso.vec
bgFileName: C:\Users\Admin\Desktop\ML\anhsai\list.txt
numPos: 15
numNeg: 13
numStages: 20
precalcValBufSize[Mb] : 256
precalcIdxBufSize[Mb] : 256
stageType: BOOST
featureType: LBP
sampleWidth: 135
sampleHeight: 120
boostType: GAB
minHitRate: 0.995
maxFalseAlarmRate: 0.5
weightTrimRate: 0.95
maxDepth: 1
maxWeakCount: 100
===== TRAINING 0-stage =====
Parameters can not be written, because file D:\train/params.xml can not be opened.
Lỗi này do bạn chưa tạo folder D:\train
Cho em hỏi tại sao chọn “-featureType LBP” mà lại có thêm “-mode ALL” ạ?
Lệnh -mode em đọc trên trang OpenCV thì nó ghi là lệnh chọn kiểu cho HAAR
Em cảm ơn!
Đúng là mình nhầm thật, trong quá trình copy dư không hay
à anh cho e hỏi thêm là cái lbpcascade_face_viscom.xml anh đã train = dataset gì và nó có hiệu quả hơn những cái đã có sẵn ko ạ?
Mình train bằng ảnh thực tế của các bãi xe ở Sài Gòn, và nó rất hiệu quả khi sử dụng cho các bãi xe đó 😀 Còn với các bãi xe mới thì mình phải khảo sát, thu thập thêm ảnh rồi train lại
chào anh hiện e đang muốn train cascade để nhận diện 1 chiếc lá trong ảnh, không biết là anh đã làm thử chưa có thể cho em xin data hoặc xml hoặc lời khuyên ạ?
hi bạn, để train thì bạn làm đủ các bước: thu thập ảnh lá, traning đủ các bước là có thể sử dụng được, nếu lỗi ở bước nào thì chụp hình lại mình sẽ hướng dẫn tiếp
vâng xin được hỏi 1 số cái ạ:
– bộ data leaf e down trên mạng về trong ảnh chỉ có mỗi chiếc lá thì có cần dùng tool khoanh ko hay có cách nào khác để chọn cả ảnh luôn ạ
– cái objectLocator trước giờ e vẫn dùng OK nhưng tự nhiên bây h bị lỗi Unhandled exception has occurred…
– Bạn có thể viết 1 script nhỏ loop qua các file ảnh để tạo ra file location.txt chứa tên ảnh, 1 đối tượng, x=0, y=0, còn width và height là kích cỡ của từng ảnh
– Bạn xem lại đường dẫn folder có chứa ký tự Unicode không?
vâng cám ơn anh ạ
e thấy trong phần 3 có nói là ảnh dương nên có bg khác nhau nhưng bộ data down về có khoảng 2000 ảnh lá trên nền trắng thì có nên dùng ko ạ?
Dùng bình thường bạn nhé, ảnh background nghĩa là ảnh không có đối tượng (negative) chứ không phải nền của ảnh dương nhé
vâng để e làm thử, xin cám ơn
e gặp lỗi này là sao hả anh?
OpenCV Error: Assertion failed (_img.cols == winSize.width) in CvCascadeImageReader::NegReader::get, file C:\builds\2_4_PackSlave-win64-vc12-shared\opencv\apps\traincascade\imagestorage.cpp, line 92
Có thể là ảnh quá lớn, bạn kiểm tra lại các ảnh xem có ảnh nào chưa resize không
vâng e train theo lệnh này thì ko được anh ạ, độ chính xác quá thấp luôn
opencv_traincascade -data E:\Leaf -vec Leaf.vec -bg D:\test\negatives\negatives\bg.txt -numPos 1700 -numNeg 3000 -w 30 -h 20 -minHitRate 0.999999 -featureType LBP
đúng rồi, có 1700 ảnh thôi mà, 4000-5000 ảnh mới đủ chính xác. Bài viết này chỉ giúp các bạn hiểu cách làm thôi
á, e cứ nghĩ hơn 1000 là nhiều rồi chứ :v
đối với bài nhận dạng khẩu trang a mới đăng e có tham khảo nhưng thấy code khó quá e dốt ko hiểu được, e vẫn tiếp tục train cascade theo bài này vì e thấy nó dễ và kết quả nó cũng nhận rất tốt mặt đeo khẩu trang nhưng có 1 vấn đề là nó nhận luôn cả mặt ko đeo khẩu trang anh ạ. có cách nào khắc phục cái này để 1 phát ăn ngay = cascade được ko ạ?
Nếu bạn muốn chỉ nhận ra khuôn mặt có đeo thì tất cả khuôn mặt không đeo khẩu trang bạn đưa vào ảnh negative nhé
e cũng bỏ nhiều ảnh ko đeo + với bộ negatives của a mà sao nó vẫn nhận luôn mặt ko đeo :v
Bạn kiểm tra lại các điều sau nếu muốn chỉ detect mặt có đeo khẩu trang:
1. Bộ ảnh dương không có khuôn mặt không đeo
2. Bộ ảnh âm không có khuôn mặt đeo khẩu trang
3. Bộ ảnh dữ liệu phải đủ nhiều (hơn 1000 ảnh)
Nếu đã làm đúng 3 điều trên thì cứ thấy ảnh nào sai thì thu thập rồi cho học lại nhiều lần nó mới khôn được
vâng cám ơn a
cám ơn a nhiều lắm, nhờ những lời khuyên của a mà e làm được rồi, tốc độ phát hiện cũng cao, e định bỏ nó vô làm 1 cái hệ thống nhắc nhở khi có người ko đeo KT, khi e bỏ 1 file mp3 vào để nhắc nhở thì có khi đeo KT rồi nhưng nó vẫn nhắc liên tục và phát cái file mp3 này nó làm chậm webcam, a cho e xin lời khuyên về cái này với
Mình không nghĩ là file mp3 làm chậm đâu mà do code detect hơi chậm. Còn nếu bạn xác định chính xác nguyên nhân là do file mp3 (không play thì detect nhanh) thì làm như sau:
– Nếu bạn sử dụng Python thì dùng lib pygame
– Nếu bạn sử dụng ngôn ngữ khác thì chạy bất đồng bộ (thread/async) để tránh ảnh hưởng thread chính
kiểu như khi nó phát file mp3 thì cái khung cam nó bị đơ lại ấy anh, để e thử pygame, nhân tiện thì a cho e hỏi a có bán rasberry pi ko ạ :D?
Mình không có bán nha bạn vì mình làm dự án thôi
vâng, a mua pi và các thiết bị như cam, loa, cảm biến nhiệt… ở đâu vậy ạ có thể chỉ e mua với :v
Mình mua ở các tiệm sau nhé:
https://nshopvn.com/
https://hshop.vn/
https://www.lazada.vn/
và https://shopee.vn/ nhé
cám ơn rất nhiều ^^
hiện e muốn làm 1 con raspberry pi để nhận diện khuôn mặt, đo thân nhiệt và phát ra lời cảnh báo nhưng e ko rành nên ko biết phải mua những thiết bị nào, nhờ a tư vấn giúp e để được mô hình có giá rẻ mà hoạt động ổn ạ
Phát hiện khuôn mặt hay nhận diện? Nếu chỉ phát hiện thì dùng Pi3 hay Pi4 đều được.
Còn do thân nhiệt thì thiết bị xài tốt cũng khoảng 10tr trở lên nhé, rẻ hơn nó trả kết quả sai bét à.
phát hiện a, e kiếm module rẻ đo chơi học thuật thôi à :D, nào h chưa biết tới mấy này nên mua nghiên cứu
Bạn ở Sài Gòn hay ở tỉnh nào? Nếu ở SG thì chat với mình https://www.facebook.com/vohungvi/
e ở Sóc Trăng a ^^