تشخیص فاصله اجتماعی با رزبری پای و OpenCV
محتویات
در زمان همه گیری ویروس کرونا ، فاصله اجتماعی یک روش موثر برای کاهش سرعت انتقال ویروس است. به افراد توصیه می شود تماس خود را با یکدیگر به حداقل برسانند تا خطر انتقال بیماری از طریق تماس مستقیم به حداقل برسد.
در این پروژه رزبری پای ما میخواهیم با استفاده از OpenCV تصاویر را تحلیل کنیم و فاصله اجتماعی بین افراد را تشخیص دهیم. رزبری پای همیشه انتخاب خوبی برای پروژه های پردازش تصویر است زیرا حافظه و سرعت بیشتری نسبت به بقیه کنترلر ها دارد.
فیلم زیر به شما در درک نحوه کار این پروژه کمک میکند.
در این پروژه ما فقط به رزبری پای 4 و OpenCV نیاز داریم. OpenCV برای پردازش تصاویر دیجیتال استفاده میشود و یکی از رایج ترین برنامه ها برای پروژه های پردازش تصاویر دیجیتال و … است.
پیشنهاد میکنم پروژه اندازه گیری جمعیت با پردازش تصویر رزبری پای و OpenCV را مشاهده کنید.
یولو YOLO
YOLO یولو (You Only Look Once) یک شبکه عصبی Convolution هوشمند برای تشخیص شی در تصاویر زنده است. YOLOv3 آخرین نوع الگوریتم تشخیص شی است و YOLO می تواند 80 شی مختلف را در تصاویر و فیلم ها تشخیص دهد و بسیار سریع و دارای دقت بسیار عالی است. این الگوریتم یک شبکه عصبی واحد را برای کل تصویر اعمال می کند ، سپس تصویر را منطقه منطقه جدا می کند و جعبه ها و احتمالات هر منطقه را محاسبه می کند. مدل Base YOLO می تواند تصاویر زنده را با سرعت 45 فریم در ثانیه پردازش کند. مدل YOLO از سایر روشهای تشخیص مانند SSD و R-CNN بهتر عمل می کند.
مدل YOLOV3 را که می خواهیم در این پروژه استفاده کنیم ، می توانید از اینجا بارگیری کنید.
نصب بسته های مورد نیاز
در این پروژه ما به بعضی از بسته ها نیاز داریم. مهم ترین بسته OpenCV است که میتوانید آموزش نصب OpenCV را مشاهده کنید. نحوه نصب بقیه بسته ها در زیر توضیح داده شده است.
آموزش نصب imutils
imutils برای اجرای چند عملکرد لازم پردازش تصویر مثل ترجمه ، چرخش ، تغییر اندازه ، اسکلت بندی و نمایش آسان تر تصاویر Matplotlib با OpenCV استفاده می شود. بنابراین با استفاده از دستور زیر imutils را نصب کنید:
pip3 install imutils
آموزش نصب NumPy
NumPy کتابخانه اصلی محاسبات علمی است که شامل یک شی آرایه n بعدی قدرتمند است و ابزارهایی را برای ادغام C ، C ++ و غیره فراهم می کند.
Pip3 install numpy
کد پروژه تشخیص فاصله اجتماعی با رزبری پای
کد کامل در انتهای صفحه آورده شده است. در اینجا ما بخش های مهم کد را توضیح می دهیم. با شروع کد ، همه کتابخانه های مورد نیاز را که قرار است در این پروژه استفاده شوند وارد میکنیم.
import numpy as np import cv2 import imutils import os import time
از تابع Check ()
برای محاسبه فاصله بین دو شی objects یا دو نقطه در یک قاب فیلم استفاده می شود. نقاط a و b نشانگر دو جسم در کادر است. از این دو نقطه برای محاسبه فاصله بین اجسام استفاده می شود.
def Check(a, b): dist = ((a[0] - b[0]) ** 2 + 550 / ((a[1] + b[1]) / 2) * (a[1] - b[1]) ** 2) ** 0.5 calibration = (a[1] + b[1]) / 2 if 0 < dist < 0.25 * calibration: return True else: return False
از تابع setup برای تنظیم مسیر های YOLO ، پرونده cfg ، پرونده COCO استفاده می شود. ماژول os.path برای دستکاری نام و نام خانوادگی مشترک استفاده می شود. os.path.join ()
ماژول یک زیر ماژول از os.path است و برای پیوستن هوشمندانه یک یا چند مولفه مسیر استفاده می شود. از روش () cv2.dnn.readNetFromDarknet
برای بارگذاری وزنهای ذخیره شده در شبکه استفاده می شود. پس از بارگیری اوزان ، لیست تمام لایه های مورد استفاده در شبکه را با استفاده از مدل net.getLayerNames استخراج کنید.
def Setup(yolo): global neural_net, ln, LABELS weights = os.path.sep.join([yolo, "yolov3.weights"]) config = os.path.sep.join([yolo, "yolov3.cfg"]) labelsPath = os.path.sep.join([yolo, "coco.names"]) LABELS = open(labelsPath).read().strip().split("\n") neural_net = cv2.dnn.readNetFromDarknet(config, weights) ln = neural_net.getLayerNames() ln = [ln[i[0] - 1] for i in neural_net.getUnconnectedOutLayers()]
در داخل عملکرد پردازش تصویر ، ما یک فریم از ویدئو می گیریم و سپس آن را پردازش می کنیم تا بتواند فاصله اجتماعی بین هر یک از افراد را تشخیص دهد. در دو خط اول عملکرد ، ما در ابتدا ابعاد قاب فیلم (W ، H) را به صورت (None ، None) تنظیم می کنیم. در خط بعدی ، از روش cv2.dnn.blobFromImage برای بارگذاری فریم ها به صورت دسته ای و اجرای آنها از طریق شبکه استفاده کردیم. عملکرد blob تفریق ، مقیاس گذاری و تغییر کانال روی یک قاب را انجام می دهد.
(H, W) = (None, None) frame = image.copy() if W is None or H is None: (H, W) = frame.shape[:2] blob = cv2.dnn.blobFromImage(frame, 1 / 255.0, (416, 416), swapRB=True, crop=False) neural_net.setInput(blob) starttime = time.time() layerOutputs = neural_net.forward(ln)
لایه های خروجی از YOLO از مجموعه ای از مقادیر تشکیل شده است. این مقادیر به ما کمک می کند تا مشخص کنیم کدام شی متعلق به کدام کلاس است. ما بر روی هر خروجی در layerOutput حلقه می زنیم و همانطور که افراد را ردیابی می کنیم ، برچسب کلاس را “person” قرار می دهیم. از هر تشخیص ، یک جعبه محدود می گیریم که مرکز X ، مرکز Y ، عرض و ارتفاع جعبه را برای تشخیص در خروجی به ما می دهد:
scores = detection[5:] maxi_class = np.argmax(scores) confidence = scores[maxi_class] if LABELS[maxi_class] == "person": if confidence > 0.5: box = detection[0:4] * np.array([W, H, W, H]) (centerX, centerY, width, height) = box.astype("int") x = int(centerX - (width / 2)) y = int(centerY - (height / 2)) outline.append([x, y, int(width), int(height)]) confidences.append(float(confidence))
پس از آن ، فاصله مرکز جعبه فعلی را با سایر جعبه های شناسایی شده محاسبه میکنیم. اگر جعبه ها نزدیک هستند ، وضعیت را به true تغییر میدهیم.
for i in range(len(center)): for j in range(len(center)): close = Check(center[i], center[j]) if close: pairs.append([center[i], center[j]]) status[i] = True status[j] = True index = 0
در خطوط بعدی ، با استفاده از ابعاد جعبه ای که از ماژول دریافت کرده ایم ، یک مستطیل به دور شخص میکشیم، سپس جعبه را ایمن یا نا امن بررسی میکنیم. اگر فاصله بین جعبه ها نزدیک باشد ، رنگ جعبه قرمز رنگ می شود در غیر این صورت جعبه سبز رنگ می شود.
(x, y) = (outline[i][0], outline[i][1]) (w, h) = (outline[i][2], outline[i][3]) if status[index] == True: cv2.rectangle(frame, (x, y), (x + w, y + h), (0, 0, 150), 2) elif status[index] == False: cv2.rectangle(frame, (x, y), (x + w, y + h), (0, 255, 0), 2)
اکنون در داخل عملکرد حلقه ، ما در حال خواندن هر فریم از فیلم هستیم و سپس پردازش هر فریم را برای محاسبه فاصله بین افراد انجام می دهیم.
ret, frame = cap.read() if not ret: break current_img = frame.copy() current_img = imutils.resize(current_img, width=480) video = current_img.shape frameno += 1 if(frameno%2 == 0 or frameno == 1): Setup(yolo) ImageProcess(current_img) Frame = processedImg
در خطوط بعدی ، از تابع cv2.VideoWriter ()
برای ذخیره فیلم خروجی در مکانی که توسط opname مشخص شده و قبلاً تعریف کردیم ، استفاده میکنیم.
if create is None: fourcc = cv2.VideoWriter_fourcc(*'XVID') create = cv2.VideoWriter(opname, fourcc, 30, (Frame.shape[1], Frame.shape[0]), True) create.write(Frame)
فیلم پروژه تشخیص فاصله اجتماعی
پس از آماده شدن کد ، ترمینال Pi را باز کنید و به دایرکتوری پروژه بروید. کد ، مدل Yolo و فیلم نمایشی باید در همان پوشه باشد.
پس از ورود به دایرکتوری پروژه ، دستور زیر را برای شروع کد اجرا کنید:
python3 detector.py
شما میتوانید این پروژه را با فیلم های از قبل ضبط شده طراحی کنید یا حتی به جای استفاده از فیلم ، می توانید با جایگزینی
cv2.VideoCapture (input)
با
cv2.VideoCapture (0)
در خط 98 کد ، این کد را با دوربین رزبری پای تست کنید.
موارد موجود در فایل : سورس کامل
برای دانلود فایل ها باید حساب کاربری داشته باشید ثبت نام / ورود