- ส่วนประกอบที่จำเป็น
- YOLO
- การติดตั้ง OpenCV ใน Raspberry Pi
- การติดตั้งแพ็คเกจที่จำเป็นอื่น ๆ ใน Raspberry Pi
- คำอธิบายโปรแกรม
- การทดสอบโครงการเครื่องตรวจจับระยะห่างทางสังคม
ในช่วงเวลาของ Covid-19 การห่างเหินทางสังคมเป็นวิธีที่มีประสิทธิภาพในการชะลอการแพร่กระจายของไวรัสที่ติดเชื้อ ขอแนะนำให้ผู้คนลดการติดต่อซึ่งกันและกันเพื่อลดความเสี่ยงของการแพร่กระจายของโรคผ่านการสัมผัสโดยตรง การรักษาระยะห่างที่ปลอดภัยเป็นเรื่องท้าทายสำหรับหลาย ๆ สถานที่เช่นโรงงานธนาคารรถบัสหรือสถานีรถไฟเป็นต้น
ดังนั้นในความต่อเนื่องของโครงการความปลอดภัยของเราก่อนหน้านี้มาลาเช่นเครื่องเจลทำความสะอาดอัตโนมัติและการตรวจสอบอุณหภูมิสัมผัสที่นี่เราจะไปสร้างระบบสังคม Distancing ตรวจจับโดยใช้ OpenCV และราสเบอร์รี่ Pi เราจะใช้น้ำหนักของ YOLO v3 Object Detection Algorithm กับโมดูล Deep Neural Network
Raspberry Pi เป็นทางเลือกที่ดีสำหรับโครงการประมวลผลภาพเนื่องจากมีหน่วยความจำและความเร็วมากกว่าตัวควบคุมอื่น ๆ ก่อนหน้านี้เราใช้ Raspberry Pi สำหรับโครงการประมวลผลภาพที่ซับซ้อนบางอย่างเช่นการตรวจจับจุดสังเกตบนใบหน้าและแอปพลิเคชันจดจำใบหน้า
ส่วนประกอบที่จำเป็น
- Raspberry Pi 4
ที่นี่เราต้องการ RPi 4 ที่ติดตั้ง OpenCV เท่านั้น OpenCV ใช้ที่นี่สำหรับการประมวลผลภาพดิจิทัล แอพพลิเคชั่นที่พบบ่อยที่สุดของ Digital Image Processing ได้แก่ การตรวจจับวัตถุการจดจำใบหน้าและตัวนับคน
YOLO
YOLO (คุณมองเพียงครั้งเดียว) เป็นโครงข่ายประสาทเทียมอัจฉริยะ (CNN) สำหรับการตรวจจับวัตถุแบบเรียลไทม์ YOLOv3 ซึ่งเป็นตัวแปรล่าสุดของอัลกอริธึมการตรวจจับวัตถุ YOLO สามารถจดจำวัตถุต่างๆได้ 80 ชิ้นในรูปภาพและวิดีโอและมันเร็วมากและมีความแม่นยำที่ยอดเยี่ยม อัลกอริทึมใช้โครงข่ายประสาทเทียมเดียวกับภาพทั้งหมดจากนั้นแยกภาพออกเป็นพื้นที่และคำนวณกรอบขอบเขตและความน่าจะเป็นสำหรับแต่ละพื้นที่ โมเดล YOLO พื้นฐานสามารถประมวลผลภาพแบบเรียลไทม์ที่ 45 เฟรมต่อวินาที รุ่น YOLO มีประสิทธิภาพดีกว่าวิธีการตรวจจับอื่น ๆ เช่น SSD และ R-CNN
รุ่น YOLOV3 ที่เรากำลังจะใช้ในโครงการนี้สามารถดาวน์โหลดได้จากที่นี่
การติดตั้ง OpenCV ใน Raspberry Pi
ก่อนที่จะติดตั้ง OpenCV และการอ้างอิงอื่น ๆ Raspberry Pi จะต้องได้รับการอัปเดตอย่างสมบูรณ์ ใช้คำสั่งด้านล่างเพื่ออัปเดต Raspberry Pi เป็นเวอร์ชันล่าสุด:
อัปเดต sudo apt-get
จากนั้นใช้คำสั่งต่อไปนี้เพื่อติดตั้งการอ้างอิงที่จำเป็นสำหรับการติดตั้ง OpenCV บน Raspberry Pi ของคุณ
sudo apt-get install libhdf5-dev -y sudo apt-get install libhdf5-serial-dev –y sudo apt-get install libatlas-base-dev –y sudo apt-get install libjasper-dev -y sudo apt-get install libqtgui4 - sudo apt-get install libqt4-test –y
สุดท้ายติดตั้ง OpenCV บน Raspberry Pi โดยใช้คำสั่งด้านล่าง
pip3 ติดตั้ง opencv-Contrib-python == 4.1.0.25
หากคุณยังใหม่กับ OpenCV ให้ตรวจสอบบทช่วยสอน OpenCV ก่อนหน้าของเราด้วย Raspberry pi:
- การติดตั้ง OpenCV บน Raspberry Pi โดยใช้ CMake
- การจดจำใบหน้าแบบเรียลไทม์ด้วย Raspberry Pi และ OpenCV
- การจดจำป้ายทะเบียนโดยใช้ Raspberry Pi และ OpenCV
- การประมาณขนาดฝูงชนโดยใช้ OpenCV และ Raspberry Pi
นอกจากนี้เรายังได้สร้างชุดบทเรียน OpenCV โดยเริ่มตั้งแต่ระดับเริ่มต้น
การติดตั้งแพ็คเกจที่จำเป็นอื่น ๆ ใน Raspberry Pi
ก่อนที่จะเขียนโปรแกรม Raspberry Pi สำหรับเครื่องตรวจจับระยะทางโซเชียลให้ติดตั้งแพ็คเกจอื่น ๆ ที่จำเป็น
การติดตั้ง imutils: imutils ใช้เพื่อสร้างฟังก์ชันการประมวลผลภาพที่จำเป็นเช่นการแปลการหมุนการปรับขนาดโครงกระดูกและการแสดงภาพ Matplotlib ง่ายขึ้นด้วย OpenCV ใช้คำสั่งด้านล่างเพื่อติดตั้ง imutils:
pip3 ติดตั้ง imutils
คำอธิบายโปรแกรม
รหัสที่สมบูรณ์จะได้รับที่ส่วนท้ายของหน้า ที่นี่เรากำลังอธิบายส่วนสำคัญของโค้ดเพื่อคำอธิบายที่ดีขึ้น
ดังนั้นเมื่อเริ่มต้นรหัสให้นำเข้าไลบรารีที่จำเป็นทั้งหมดที่จะใช้ในโครงการนี้
import numpy เป็น np import cv2 import imutils import os เวลานำเข้า
ฟังก์ชัน Check () ใช้เพื่อคำนวณระยะห่างระหว่างวัตถุสองชิ้นหรือสองจุดในเฟรมวิดีโอ จุดaและbแสดงถึงวัตถุสองชิ้นในเฟรม จุดทั้งสองนี้ใช้ในการคำนวณระยะทางแบบยุคลิดระหว่างวัตถุ
ตรวจสอบ def (a, b): dist = ((a - b) ** 2 + 550 / ((a + b) / 2) * (a - b) ** 2) ** 0.5 สอบเทียบ = (a + b) / 2 if 0 <dist <0.25 * calibration: return True else: return False
ฟังก์ชันการตั้งค่าใช้เพื่อกำหนดเส้นทางสำหรับน้ำหนัก YOLO, ไฟล์ cfg, ไฟล์ชื่อ COCO โมดูล os.path ใช้สำหรับการจัดการชื่อพา ธ ทั่วไปโมดูล os.path.join () เป็นโมดูลย่อยของ os.path และใช้เพื่อเข้าร่วมคอมโพเนนต์พา ธ ตั้งแต่หนึ่งรายการขึ้นไปอย่างชาญฉลาด cv2.dnn.readNetFromDarknet () วิธีการใช้เพื่อโหลดน้ำหนักที่บันทึกไว้ในเครือข่าย หลังจากโหลดน้ำหนักแล้วให้แยกรายการของเลเยอร์ทั้งหมดที่ใช้ในเครือข่ายโดยใช้โมเดล net.getLayerNames
การตั้งค่า def (yolo): global neural_net, ln, LABELS weights = os.path.sep.join () config = os.path.sep.join () labelPath = os.path.sep.join () LABELS = เปิด (labelPath).read (). strip (). split ("\ n") neural_net = cv2.dnn.readNetFromDarknet (config, weights) ln = neural_net.getLayerNames () ln = - 1] สำหรับ i ใน neural_net.getUnconnectedOutLayers ()]
ภายในฟังก์ชันการประมวลผลภาพเราถ่ายวิดีโอเฟรมเดียวแล้วประมวลผลเพื่อตรวจจับระยะห่างทางสังคมระหว่างทุกคนในฝูงชน ในสองบรรทัดแรกของฟังก์ชันเราตั้งค่าขนาดของเฟรมวิดีโอ (W, H) เป็น (ไม่มี, ไม่มี) ในตอนแรก ในบรรทัดถัดไปเราใช้ เมธอด cv2.dnn.blobFromImage () เพื่อโหลดเฟรมในแบตช์และรันผ่านเครือข่าย ฟังก์ชันหยดจะทำการลบค่าเฉลี่ยการ ปรับขนาดและการสลับช่องบนเฟรม
(H, W) = (ไม่มี, ไม่มี) frame = image.copy () ถ้า W คือไม่มีหรือ H คือไม่มี: (H, W) = frame.shape blob = cv2.dnn.blobFromImage (เฟรม 1 / 255.0, (416, 416), swapRB = True, crop = False) neural_net.setInput (blob) starttime = time.time () layerOutputs = neural_net.forward (ln)
เอาต์พุตเลเยอร์จาก YOLO ประกอบด้วยชุดของค่า ค่าเหล่านี้ช่วยให้เรากำหนดว่า วัตถุใด เป็นของ คลาส ใด เราวนซ้ำทุกเอาต์พุตใน LayerOutputs และในขณะที่เราตรวจจับคนเราจึงตั้งค่าป้ายกำกับคลาสเป็น "person" จากการตรวจจับแต่ละครั้งเราจะได้กล่องขอบเขตที่ให้เรา X center, Y center, Width และ Height ของกล่องสำหรับตรวจจับในเอาต์พุต:
คะแนน = การตรวจจับ maxi_class = np.argmax (คะแนน) ความเชื่อมั่น = คะแนนถ้า LABELS == "คน": ถ้าความมั่นใจ> 0.5: box = detection * np.array () (centerX, centerY, width, height) = box.astype ("int") x = int (centerX - (width / 2)) y = int (centerY - (height / 2)) outline.append () confidences.append (float (ความมั่นใจ))
หลังจากนั้นให้คำนวณระยะห่างระหว่างศูนย์กลางของกล่องปัจจุบันกับกล่องอื่น ๆ ที่ตรวจพบทั้งหมด หากกล่องที่ล้อมรอบอยู่ใกล้ให้เปลี่ยนสถานะเป็นจริง
สำหรับฉันอยู่ในช่วง (len (กลาง)): สำหรับ j ในช่วง (len (กลาง)): ปิด = ตรวจสอบ (ศูนย์, ศูนย์) หากปิด: pairs.append (, center]) สถานะ = สถานะจริง = ดัชนีจริง = 0
ในบรรทัดถัดไปให้วาดสี่เหลี่ยมผืนผ้ารอบ ๆ บุคคลโดยใช้ขนาดกล่องที่เราได้รับจากแบบจำลองจากนั้นตรวจสอบว่ากล่องนั้นปลอดภัยหรือไม่ปลอดภัย หากระยะห่างระหว่างกล่องใกล้เคียงกันสีของกล่องจะเป็นสีแดงมิฉะนั้นกล่องจะเป็นสีเขียว
(x, y) = (โครงร่าง, โครงร่าง) (w, h) = (โครงร่าง, โครงร่าง) ถ้าสถานะ == จริง: cv2.rectangle (เฟรม, (x, y), (x + w, y + h) (0, 0, 150), 2) สถานะ elif == เท็จ: cv2.rectangle (เฟรม, (x, y), (x + w, y + h), (0, 255, 0), 2)
ตอนนี้อยู่ในฟังก์ชัน ลูป เรากำลังอ่านทุกเฟรมของวิดีโอจากนั้นประมวลผลแต่ละเฟรมเพื่อคำนวณระยะห่างระหว่างบุคคล
ret, frame = cap.read () ถ้าไม่ ret: break current_img = frame.copy () current_img = imutils.resize (current_img, width = 480) video = current_img.shape frameno + = 1 if (frameno% 2 == 0 หรือ frameno == 1): การตั้งค่า (yolo) ImageProcess (current_img) Frame = processingImg
ในบรรทัดถัดไปใช้ ฟังก์ชัน cv2.VideoWriter () เพื่อจัดเก็บวิดีโอเอาต์พุตในตำแหน่งที่ระบุโดย opname ซึ่งเราได้กำหนดไว้ก่อนหน้านี้
ถ้าสร้างเป็นไม่มี: fourcc = cv2.VideoWriter_fourcc (* 'XVID') create = cv2.VideoWriter (opname, fourcc, 30, (Frame.shape, Frame.shape), True) create.write (Frame)
การทดสอบโครงการเครื่องตรวจจับระยะห่างทางสังคม
เมื่อรหัสของคุณพร้อมแล้วให้เปิดเทอร์มินัล Pi แล้วไปที่ไดเรกทอรีโครงการ รหัสรุ่น Yolo และวิดีโอสาธิตควรอยู่ในโฟลเดอร์เดียวกันดังที่แสดงด้านล่าง
คุณสามารถดาวน์โหลดไดเร็กทอรี YoloV3 ได้จากที่นี่วิดีโอจาก Pexels และคัดลอกรหัส Python ที่ระบุด้านล่างและวางไว้ในไดเร็กทอรีเดียวกันดังที่แสดงด้านบน
เมื่อคุณอยู่ในไดเร็กทอรีโปรเจ็กต์ให้รันคำสั่งต่อไปนี้เพื่อเริ่มโค้ด:
python3 detector.py
ฉันลองใช้รหัสนี้กับตัวอย่างวิดีโอที่ได้รับจาก Pexels สำหรับฉัน FPS นั้นช้ามากและใช้เวลาประมาณ 10 ถึง 11 นาทีในการประมวลผลวิดีโอทั้งหมด
แทนการใช้วิดีโอคุณยังสามารถทดสอบโค้ดนี้กับกล้อง Raspberry Pi โดยการเปลี่ยน cv2.VideoCapture (input) กับ cv2.VideoCapture (0) ใน 98 THบรรทัดของรหัส เรียนรู้เพิ่มเติมเกี่ยวกับการใช้ PiCamera กับ Raspberry Pi ตามลิงค์
นี่คือวิธีที่คุณสามารถใช้ OpenCV กับ Raspberry Pi เพื่อตรวจจับการละเมิดความห่างเหินทางสังคม วิดีโอและรหัสที่ส่งออกมีให้ด้านล่าง: