- ข้อกำหนดเบื้องต้น
- ขั้นตอนที่เกี่ยวข้องกับการจดจำป้ายทะเบียนโดยใช้ Raspberry Pi
- 1. การตรวจจับป้ายทะเบียน
- 2. การแบ่งกลุ่มตัวละคร
- 3. การจดจำตัวละคร
- กรณีล้มเหลวในการจดจำป้ายทะเบียน
- ตัวอย่างความสำเร็จอื่น ๆ
ความปลอดภัยเป็นปัญหาสำคัญสำหรับมนุษยชาติมาโดยตลอด วันนี้เรามีกล้องวิดีโอวงจรปิดในโรงเรียนโรงพยาบาลและสถานที่สาธารณะอื่น ๆ เพื่อให้เรารู้สึกปลอดภัย จากการสำรวจโดย HIS คาดว่ามีกล้องรักษาความปลอดภัยประมาณ 245 ล้านตัวที่ติดตั้งและใช้งานได้ในปี 2014 ซึ่งเหมือนกับมีกล้องรักษาความปลอดภัยหนึ่งตัวสำหรับทุกๆ 30 คนบนโลกใบนี้ ด้วยความก้าวหน้าทางเทคโนโลยีโดยเฉพาะอย่างยิ่งในการประมวลผลภาพและการเรียนรู้ของเครื่องทำให้กล้องเหล่านี้ฉลาดขึ้นได้โดยการฝึกอบรมให้ประมวลผลข้อมูลจากฟีดวิดีโอ
ฟีดวิดีโอจากกล้องเหล่านี้สามารถใช้ในการจดจำใบหน้าการวิเคราะห์รูปแบบการวิเคราะห์อารมณ์และอื่น ๆ อีกมากมายซึ่งจะทำให้ใกล้เคียงกับบางสิ่งอย่างเช่น“ ดวงตาของพระเจ้า” ที่แสดงในภาพยนตร์ FF7 ในความเป็นจริง บริษัท เฝ้าระวังเช่น Hikvision และอื่น ๆ อีกมากมายได้เริ่มใช้คุณสมบัติเหล่านี้ในผลิตภัณฑ์ของตนแล้ว ก่อนหน้านี้เราใช้การประมวลผลภาพ MATLAB ในการอ่านหมายเลขทะเบียนในวันนี้ในบทความนี้เราจะได้เรียนรู้วิธีการรับรู้และอ่านอนุญาตเลขที่ตบดินจากรถยนต์โดยใช้ราสเบอร์รี่ Pi และ OpenCV เราจะใช้ภาพรถแบบสุ่มจาก Google และเขียนโปรแกรมเพื่อจดจำป้ายทะเบียนโดยใช้ OpenCV Contour Detection จากนั้นอ่านหมายเลขจากป้ายทะเบียนโดยใช้ Tesseract OCR ฟังดูน่าสนใจ! งั้นมาเริ่มกันเลย
ข้อกำหนดเบื้องต้น
อย่างที่บอกไปก่อนหน้านี้เราจะใช้ OpenCV Library เพื่อตรวจจับและจดจำใบหน้า ดังนั้นอย่าลืมติดตั้ง OpenCV Library บน Raspberry Pi ก่อนดำเนินการตามบทช่วยสอนนี้ เพิ่มพลังให้ Pi ของคุณด้วยอะแดปเตอร์ 2A และเชื่อมต่อกับจอแสดงผลเพื่อการดีบักที่ง่ายขึ้น
บทช่วยสอนนี้จะไม่อธิบายว่า OpenCV ทำงานอย่างไรหากคุณสนใจที่จะเรียนรู้การประมวลผลภาพลองดูพื้นฐาน OpenCV และแบบฝึกหัดการประมวลผลภาพขั้นสูง คุณยังสามารถเรียนรู้เกี่ยวกับรูปทรงการตรวจจับหยดน้ำและอื่น ๆ ได้ในบทช่วยสอนการแบ่งส่วนภาพโดยใช้ OpenCV เราจะทำสิ่งที่คล้ายกันนี้เพื่อตรวจจับป้ายทะเบียนของรถจากภาพ
ขั้นตอนที่เกี่ยวข้องกับการจดจำป้ายทะเบียนโดยใช้ Raspberry Pi
License Plate Recognition หรือ LPR โดยย่อมีสามขั้นตอนหลัก ๆ ขั้นตอนมีดังนี้
1. การตรวจจับป้ายทะเบียน:ขั้นตอนแรกคือการตรวจจับป้ายทะเบียนจากรถ เราจะใช้ตัวเลือกรูปร่างใน OpenCV เพื่อตรวจจับวัตถุสี่เหลี่ยมเพื่อค้นหาป้ายทะเบียน ความแม่นยำสามารถปรับปรุงได้หากเราทราบขนาดสีและตำแหน่งโดยประมาณของป้ายทะเบียน โดยปกติอัลกอริทึมการตรวจจับจะได้รับการฝึกฝนตามตำแหน่งของกล้องและประเภทของป้ายทะเบียนที่ใช้ในประเทศนั้น ๆ สิ่งนี้จะยากขึ้นหากภาพไม่มีรถในกรณีนี้เราจะเพิ่มขั้นตอนเพิ่มเติมในการตรวจจับรถและป้ายทะเบียน
2. การแบ่งกลุ่มตัวละคร:เมื่อเราตรวจพบป้ายทะเบียนแล้วเราต้องครอบตัดและบันทึกเป็นภาพใหม่ อีกครั้งสามารถทำได้อย่างง่ายดายโดยใช้ OpenCV
3. การจดจำตัวอักษร:ตอนนี้ภาพใหม่ที่เราได้รับในขั้นตอนก่อนหน้านี้จะต้องมีอักขระบางตัว (ตัวเลข / ตัวอักษร) เขียนอยู่ ดังนั้นเราสามารถทำการ OCR (Optical Character Recognition) เพื่อตรวจจับหมายเลขได้ เราได้อธิบาย Optical Character Recognition (OCR) โดยใช้ Raspberry Pi แล้ว
1. การตรวจจับป้ายทะเบียน
ขั้นตอนแรกในเครื่องอ่านป้ายทะเบียน Raspberry Piคือการตรวจหาป้ายทะเบียน มาดูภาพตัวอย่างของรถและเริ่มต้นด้วยการตรวจจับป้ายทะเบียนบนรถคันนั้น จากนั้นเราจะใช้ภาพเดียวกันสำหรับการแบ่งส่วนอักขระและการจดจำตัวละครด้วย หากคุณต้องการข้ามไปที่โค้ดโดยไม่มีคำอธิบายคุณสามารถเลื่อนลงไปที่ด้านล่างของหน้านี้ซึ่งมีรหัสที่สมบูรณ์ ภาพทดสอบที่ฉันใช้สำหรับบทช่วยสอนนี้แสดงอยู่ด้านล่าง
ขั้นตอนที่ 1: การปรับขนาดภาพให้มีขนาดที่ต้องการแล้วมันสีเทารหัสสำหรับเดียวกันได้รับด้านล่าง
img = cv2.resize (img, (620,480)) สีเทา = cv2.cvtColor (img, cv2.COLOR_BGR2GRAY) # แปลงเป็นระดับสีเทา
การปรับขนาดช่วยให้เราหลีกเลี่ยงปัญหาเกี่ยวกับภาพความละเอียดที่ใหญ่ขึ้นตรวจสอบให้แน่ใจว่าป้ายทะเบียนยังคงอยู่ในเฟรมหลังจากปรับขนาดแล้ว การปรับสีเทาเป็นเรื่องปกติในทุกขั้นตอนการประมวลผลภาพ ซึ่งจะช่วยเพิ่มความเร็วในกระบวนการอื่น ๆ ที่ตามมาเราไม่ต้องจัดการกับรายละเอียดสีอีกต่อไปเมื่อประมวลผลภาพ ภาพจะเปลี่ยนเป็นแบบนี้เมื่อเสร็จขั้นตอนนี้
ขั้นตอนที่ 2:ภาพทุกภาพจะมีข้อมูลที่เป็นประโยชน์และไม่มีประโยชน์ในกรณีนี้สำหรับเรามีเพียงป้ายทะเบียนเท่านั้นที่เป็นข้อมูลที่มีประโยชน์ส่วนที่เหลือค่อนข้างไร้ประโยชน์สำหรับโปรแกรมของเรา ข้อมูลที่ไร้ประโยชน์นี้เรียกว่าสัญญาณรบกวน ปกติใช้ตัวกรองทวิภาคี (Bluring) จะลบรายละเอียดที่ไม่พึงประสงค์จากภาพ รหัสสำหรับเดียวกันคือ
สีเทา = cv2.bilateralFilter (สีเทา, 11, 17, 17)
ไวยากรณ์คือ destination_image = cv2.bilateralFilter (source_image, เส้นผ่านศูนย์กลางของพิกเซล, sigmaColor, sigmaSpace) คุณสามารถเพิ่มสีของซิกมาและช่องว่างของซิกมาจากค่า 17 เป็นค่าที่สูงขึ้นเพื่อเบลอข้อมูลพื้นหลังเพิ่มเติมได้ แต่ระวังว่าส่วนที่เป็นประโยชน์จะไม่เบลอ รูปภาพที่ส่งออกแสดงอยู่ด้านล่างดังที่คุณเห็นรายละเอียดพื้นหลัง (ต้นไม้และสิ่งปลูกสร้าง) เบลอในภาพนี้ ด้วยวิธีนี้เราสามารถหลีกเลี่ยงโปรแกรมจากการมุ่งเน้นไปที่ภูมิภาคเหล่านี้ในภายหลัง
ขั้นตอนที่ 3:ขั้นตอนต่อไปเป็นที่น่าสนใจที่เราดำเนินการตรวจจับขอบมีหลายวิธีในการทำวิธีที่ง่ายที่สุดและเป็นที่นิยมคือการใช้วิธีการขอบที่สวยงามจาก OpenCV บรรทัดที่ต้องทำเช่นเดียวกันแสดงอยู่ด้านล่าง
edged = cv2.Canny (สีเทา, 30, 200) #Perform Edge detection
ไวยากรณ์จะเป็น destination_image = cv2.Canny (source_image, thresholdValue 1, thresholdValue 2) Threshold Vale 1 และ Threshold Value 2 เป็นค่าขีด จำกัด ขั้นต่ำและสูงสุด เฉพาะขอบที่มีการไล่ระดับความเข้มมากกว่าค่าเกณฑ์ขั้นต่ำและน้อยกว่าค่าขีด จำกัด สูงสุดเท่านั้นที่จะถูกแสดง ภาพที่ได้แสดงไว้ด้านล่าง
ขั้นตอนที่ 4:ตอนนี้เราสามารถเริ่มมองหารูปทรงบนรูปภาพของเราได้แล้วเราได้เรียนรู้เกี่ยวกับวิธีค้นหารูปทรงโดยใช้ OpenCV ในบทช่วยสอนก่อนหน้านี้แล้วดังนั้นเราจึงดำเนินการต่อในลักษณะเดียวกัน
nts = cv2.findContours (edged.copy (), cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE) cnts = imutils.grab_contours (cnts) cnts = sorted (cnts, key = cv2.contourArea, reverse = True) screenCnt = None
เมื่อตรวจพบตัวนับแล้วเราจะเรียงลำดับจากใหญ่ไปเล็กและพิจารณาเฉพาะ 10 ผลลัพธ์แรกโดยไม่สนใจผลอื่น ๆ ในภาพของเราตัวนับอาจเป็นอะไรก็ได้ที่มีพื้นผิวปิด แต่จากผลลัพธ์ที่ได้ทั้งหมดจะมีหมายเลขป้ายทะเบียนเนื่องจากเป็นพื้นผิวปิดเช่นกัน
ในการกรองภาพป้ายทะเบียนจากผลลัพธ์ที่ได้รับเราจะวนซ้ำผลลัพธ์ทั้งหมดและตรวจสอบว่ามีรูปทรงสี่เหลี่ยมผืนผ้าที่มีสี่ด้านและรูปปิด เนื่องจากป้ายทะเบียนจะต้องเป็นรูปสี่เหลี่ยมผืนผ้าสี่ด้านอย่างแน่นอน
# วนซ้ำรูปทรงของเรา สำหรับ c ใน cnts: # โดยประมาณรูปร่าง peri = cv2.arcLength (c, True) ประมาณ = cv2.approxPolyDP (c, 0.018 * peri, True) # ถ้าเส้นตรงโดยประมาณของเรามีสี่จุดแล้ว # เรา สามารถสันนิษฐานได้ว่าเราพบหน้าจอของเรา ถ้า len (ประมาณ) == 4: screenCnt = แบ่งโดยประมาณ
ค่า 0.018 เป็นค่าทดลอง คุณสามารถเล่นรอบ ๆ เพื่อตรวจสอบสิ่งที่ดีที่สุดสำหรับคุณ หรือนำไปสู่ระดับถัดไปโดยใช้แมชชีนเลิร์นนิงในการฝึกตามภาพรถแล้วใช้ค่าที่เหมาะสมที่นั่น เมื่อเราพบตัวนับที่ถูกต้องแล้วให้บันทึกไว้ในตัวแปรที่เรียกว่า screenCnt จากนั้นวาดกล่องสี่เหลี่ยมผืนผ้ารอบ ๆ เพื่อให้แน่ใจว่าเราตรวจพบป้ายทะเบียนถูกต้อง
ขั้นตอนที่ 5:ตอนนี้เรารู้แล้วว่าป้ายทะเบียนอยู่ที่ใดข้อมูลที่เหลือก็ค่อนข้างไร้ประโยชน์สำหรับเรา ดังนั้นเราสามารถดำเนินการปิดบังภาพทั้งหมดยกเว้นสถานที่ที่เป็นป้ายทะเบียน รหัสในการทำเช่นเดียวกันแสดงอยู่ด้านล่าง
# การมาสก์ส่วนอื่นที่ไม่ใช่มาส ก์ แผ่นตัวเลข= np.zeros (gray.shape, np.uint8) new_image = cv2.drawContours (มาสก์,, 0,255, -1,) new_image = cv2.bitwise_and (img, img, mask = หน้ากาก)
ภาพใหม่ที่มาสก์จะปรากฏขึ้นด้านล่าง
2. การแบ่งกลุ่มตัวละคร
ขั้นตอนต่อไปในRaspberry Pi Number Plate Recognitionคือการแบ่งส่วนป้ายทะเบียนออกจากรูปภาพโดยการครอบตัดและบันทึกเป็นภาพใหม่ จากนั้นเราสามารถใช้ภาพนี้เพื่อตรวจจับอักขระในนั้นได้ รหัสสำหรับครอบตัดรูป roi (ภูมิภาคที่สนใจ) ในรูปแบบภาพหลักแสดงอยู่ด้านล่าง
# ตอนนี้ครอบตัด (x, y) = np โดยที่ (mask == 255) (topx, topy) = (np.min (x), np.min (y)) (bottomx, bottomy) = (np.max (x), np.max (y)) ครอบตัด = สีเทา
ภาพที่ได้แสดงไว้ด้านล่าง โดยปกติเมื่อเพิ่มการครอบตัดรูปภาพแล้วเรายังสามารถทำให้เป็นสีเทาและขอบได้หากต้องการ สิ่งนี้ทำเพื่อปรับปรุงการจดจำอักขระในขั้นตอนต่อไป อย่างไรก็ตามฉันพบว่ามันใช้งานได้ดีแม้จะเป็นภาพต้นฉบับก็ตาม
3. การจดจำตัวละคร
ขั้นตอนสุดท้ายในนี้ราสเบอร์รี่ Pi หมายเลขทะเบียนการรับรู้เป็นจริงอ่านข้อมูลหมายเลขทะเบียนจากภาพที่แบ่งกลุ่มเราจะใช้แพ็คเกจ pytesseract เพื่ออ่านอักขระจากรูปภาพเช่นเดียวกับที่เราทำในบทช่วยสอนก่อนหน้านี้ รหัสสำหรับเดียวกันได้รับด้านล่าง
# อ่านป้ายทะเบียน text = pytesseract.image_to_string (Cropped, config = '- psm 11') print ("Detected Number is:", text)
เราได้อธิบายวิธีกำหนดค่าเครื่องมือ Tesseract แล้วดังนั้นที่นี่อีกครั้งหากจำเป็นเราสามารถกำหนดค่า Tesseract OCR เพื่อให้ได้ผลลัพธ์ที่ดีขึ้นหากจำเป็น จากนั้นอักขระที่ตรวจพบจะถูกพิมพ์บนคอนโซล เมื่อรวบรวมผลลัพธ์จะแสดงดังต่อไปนี้
ดังที่คุณเห็นภาพต้นฉบับมีหมายเลข“ HR 25 BR9044” อยู่และโปรแกรมของเราตรวจพบว่ามีการพิมพ์ค่าเดียวกันบนหน้าจอ
กรณีล้มเหลวในการจดจำป้ายทะเบียน
ไฟล์โครงการที่สมบูรณ์นี้สามารถดาวน์โหลดRaspberry Pi License Plate Recognitionได้จากที่นี่ซึ่งมีโปรแกรมและภาพทดสอบที่เราใช้ตรวจสอบโปรแกรมของเรา โดยไม่ต้องถูกกล่าวว่าก็คือการจะจำได้ว่าผลที่ได้จากวิธีการนี้จะไม่ถูกต้อง ความถูกต้องขึ้นอยู่กับความคมชัดของภาพ, ปฐมนิเทศ, แสง ฯลฯ เพื่อให้ได้ผลลัพธ์ที่ดีขึ้นคุณสามารถลองใช้อัลกอริทึมการเรียนรู้ของเครื่องควบคู่ไปด้วย
เพื่อให้ได้แนวคิดลองดูตัวอย่างอื่นที่รถไม่หันเข้าหากล้องโดยตรง
อย่างที่คุณเห็นโปรแกรมของเราสามารถตรวจจับป้ายทะเบียนได้อย่างถูกต้องและครอบตัด แต่ไลบรารี Tesseract ไม่สามารถจดจำตัวอักษรได้อย่างถูกต้อง แทนที่จะเป็น“ TS 08 UE 3396” จริง OCR ยอมรับว่าเป็น“ 1508 ye 3396” ปัญหานี้สามารถแก้ไขได้โดยการใช้ภาพการวางแนวทางที่ดีกว่าหรือโดยการกำหนดค่า Tesseract เครื่องยนต์
อีกกรณีหนึ่งที่เลวร้ายที่สุดคือการที่รูปร่างไม่สามารถตรวจจับป้ายทะเบียนได้อย่างถูกต้อง ภาพด้านล่างมีข้อมูลพื้นหลังมากเกินไปและแสงที่ไม่ดีซึ่งโปรแกรมยังไม่สามารถระบุป้ายทะเบียนจากหมายเลขได้ ในกรณีนี้เราต้องถ่ายทอดการเรียนรู้ของเครื่องอีกครั้งหรือปรับปรุงคุณภาพของภาพ
ตัวอย่างความสำเร็จอื่น ๆ
เวลาส่วนใหญ่ของคุณภาพของภาพและการวางแนวถูกต้องโปรแกรมสามารถระบุป้ายทะเบียนและอ่านหมายเลขจากมันได้ ภาพสแนปด้านล่างแสดงผลลัพธ์ที่ประสบความสำเร็จเพียงไม่กี่รายการ ภาพทดสอบทั้งหมดและรหัสที่ใช้ที่นี่อีกครั้งจะอยู่ในไฟล์ ZIP ที่ให้ไว้ที่นี่
หวังว่าคุณจะเข้าใจAutomatic Number Plate Recognition โดยใช้ Raspberry Piและสนุกกับการสร้างสิ่งดีๆด้วยตัวคุณเอง คุณคิดว่าOpenCV และ Tesseractสามารถทำอะไรได้อีกโปรดแจ้งให้เราทราบความคิดเห็นของคุณในส่วนความคิดเห็น หากคุณมีคำถามใด ๆ เกี่ยวกับบทความนี้โปรดอย่าลังเลที่จะทิ้งไว้ในส่วนความคิดเห็นด้านล่างหรือใช้ฟอรัมสำหรับคำถามทางเทคนิคอื่น ๆ