پروژه الکترونیکپروژه های پایتونپروژه های پردازش تصویرپروژه های رزبری پای

تشخیص حرکت دوربین مدار بسته با رزبری پای (هشدار و OpenCV)

OpenCV ابزاری قدرتمند است و همراه با رزبری پای می تواند کابرد های فراوانی داشته باشد. در مقاله قبلی مشاهده فیلم دوربین مدار بسته در رزبری پای را یاد گرفتیم که چگونه فیلم DVR دوربین مداربسته را با استفاده از RTSP دریافت کنیم. در این مقاله ، ما می آموزیم که چگونه از قدرت OpenCV استفاده کرده و یک سیستم تشخیص حرکت مبتنی بر رزبری پای طراحی کنیم که در آن تصاویر را به صورت زنده از دوربین مدار بسته دریافت شوند. پس از دریافت تصاویر را تحلیل میکنیم و در صورتی که حرکت تشخیص داده شود هشدار فعال میشود.

ما یک اسکریپت پایتون را خواهیم نوشت که میتواند چهار دوربین مدار بسته را کنترل کند. اگر حرکتی در هر یک از این دوربین ها تشخیص داده شود، رزبری پای به صفحه دوربین مورد نظر میرود و مشخص میکند که چه فعالیتی انجام شده است. این پروژه دارای سرعت بالایی است و تاخیر ناچیر 1.5 ثانیه را دارد. همچنین ما یک ویژگی زنگ هشدار را اضافه کرده ایم که در صورت تشخیص حرکت باعث فعال شدن بوق میشود.

تنظیم رزبری پای با Buster و OpenCV

من از Raspberry Pi 3 B + با سیستم عامل Buster روی آن استفاده می کنم و نسخه OpenCV 4.1 است. اگر OpenCV را روی رزبری پای خود نصب ندارید، آموزش نصب OpenCV را مشاهده کنید.

زیاد تفاوتی ندارد که کدام نسخه از سیستم عامل Raspbian را روی رزبری پای خود داشته باشید اما مطمئن شوید نسخه OpenCV 4.1 یا بالاتر باشد.

اضافه کردن بازر به نمایشگر 5 اینچ رزبری پای

از لحاظ سخت افزاری ، ما چیزی به جز یک نمایشگر 5 اینچی و یک Buzzer نیاز نداریم. پس از اتصال نمایشگر 5 اینچ به رزبری پای، میتوانید مستقیما بازر را در پشت نمایشگر نصب کنید زیرا در آنچا بعضی از پین های GPIO وجود دارند.

اضافه کردن بازر به نمایشگر 5 اینچ رزبری پای

اگر شما به استفاده از پین های ورودی / خروجی بیشتر علاقه دارید ،تصویر زیر برای شما مفید خواهد بود. همانطور که در بین پین های گسترده مشاهده می کنید ، بیشتر پین ها توسط خود Display برای ارتباط صفحه لمسی با رزبری پای استفاده می شوند. اما هنوز ، پین های 3،5،7،8،10،11،12،13،15،16 و 24 را داریم که ارتباطی ندارند و می توانیم از آن برای برنامه های خود استفاده کنیم. در این آموزش ، من یک بازر را به GPIO 3 وصل کردم.

توضیحات پین های رزبری پای

برنامه نویسی رزبری پای برای تشخیص حرکت دوربین مدار بسته

کد کامل پروژه در انتهای صفحه قرار داده شده است. در اینجا بعضی از قسمت های کد را بررسی خواهیم کرد. پیشنهاد میکنم جهت آشنایی بیشتر، آموزش پردازش تصویر با OpenCV در پایتون را مشاهده کنید.

نظارت بر چندین دوربین بدون تأخیر در رزبری پای با استفاده از RTSP

اگر میخواهید آردوینو را به صورت اصولی و پروژه محور (برنامه نویسی حرفه ای، ارتباط آردوینو با اندروید، ساخت ربات با آردوینو) یاد بگیرید، روی دوره آموزش آردوینو کلیک کنید.

قسمت چالش برانگیز در ساخت این کار کاهش بار وارد بر رزبری پای برای جلوگیری از تأخیر در پخش بود. در ابتدا سعی کردم بین هر چهار دوربین جابجا شوم و به دنبال حرکت باشم اما دارای تاخیر زیادی بود (حدود 10 ثانیه). بنابراین من هر چهار دوربین را با یک تصویر واحد ترکیب کردم و تمام فعالیت های تشخیص حرکت را روی آن تصویر انجام دادم. من دو عملکرد نوشتم ، یعنی create a camera و read camera.

از عملکرد create a camera برای باز کردن دوربین با شماره کانال مربوطه استفاده می شود. توجه داشته باشید که URL RTSP با “02” خاتمه می یابد ، این بدان معنی است که من از  sub-stream زیر جریان ویدئو استفاده می کنم که دارای رزولوشن پایین است اما خواندن آن سریعتر است. همچنین ، نوع کدک ویدیویی که استفاده می کنید نیز به سرعت کمک می کند ، من کدهای مختلفی را آزمایش کردم و متوجه شدم FFMPEG مناسب است.

def create_camera (channel):
    rtsp = "rtsp://" + rtsp_username + ":" + rtsp_password + "@" + rtsp_IP + ":554/Streaming/channels/" + channel + "02" #change the IP to suit yours
    cap = cv2.VideoCapture(rtsp, cv2.CAP_FFMPEG)
    cap.set(3, cam_width)  # ID number for width is 3
    cap.set(4, cam_height)  # ID number for height is 480
    cap.set(10, 100)  # ID number for brightness is 10
    return cap

در عملکرد read camera ، ما هر چهار دوربین یعنی cam1 ، cam2 ، cam3 و cam4 را می خوانیم تا همه آنها در یک تصویر واحد به نام Main_screen ترکیب شوند. پس از آماده شدن ، ما تمام کارهای OpenCV خود را روی این تصویر انجام خواهیم داد.

def read_camera ():
    success, current_screen = cam1.read()
    Main_screen [:cam_height, :cam_width, :3] = current_screen
    success, current_screen = cam2.read()
    Main_screen[cam_height:cam_height*2, :cam_width, :3] = current_screen
    success, current_screen = cam3.read()
    Main_screen[:cam_height, cam_width:cam_width*2, :3] = current_screen
    success, current_screen = cam4.read()
    Main_screen[cam_height:cam_height*2, cam_width:cam_width*2, :3] = current_screen
    return (Main_screen)

تصویر صفحه اصلی با چهار چهار دوربین ترکیب شده مانند تصویری است که در زیر نشان داده شده است.

رزبری پای تشخیص حرکت دوربین مدار بسته

همچنین اگر در مورد این مطلب سوالی داشتید در انتهای صفحه در قسمت نظرات بپرسید

تشخیص حرکت در OpenCV با Raspberry Pi

اکنون که تصویر آماده است ، می توانیم تشخیص حرکت را شروع کنیم. در داخل حلقه while ، ما با خواندن دو فریم مختلف یعنی frame1 و frame2 شروع می کنیم ، سپس آنها را به مقیاس خاکستری تبدیل می کنیم.

frame1 = read_camera() #Read the first frame
grayImage_F1 = cv2.cvtColor(frame1, cv2.COLOR_BGR2GRAY)  # تبدیل به مقیاس خاکستری
frame2 = read_camera() #Read the 2nd frame
grayImage_F2 = cv2.cvtColor(frame2, cv2.COLOR_BGR2GRAY)

سپس ما بین این دو تصویر مقایسه انجام میدهیم تا بفهمیم که تغییری رخ داده است یا خیر.

diffImage = cv2.absdiff(grayImage_F1,grayImage_F2) #get the differance --this is cool
blurImage = cv2.GaussianBlur(diffImage, (5,5), 0)
_, thresholdImage = cv2.threshold(blurImage, 20,255,cv2.THRESH_BINARY)
dilatedImage = cv2.dilate(thresholdImage,kernal,iterations=5)

مرحله بعدی پیدا کردن کانتر (contour) و بررسی مساحت آن است ، با پیدا کردن منطقه ، می توانیم اندازه محرک را دریابیم. اگر ناحیه بزرگتر از یک مقدار مشخص شده در متغیر motion_detected باشد ، ما آن را به عنوان یک فعالیت در نظر می گیریم و یک کادر در اطراف محرک می کشیم تا برای کاربر برجسته شود.

contours, _ = cv2.findContours (dilatedImage, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
for contour in contours: #تغییرات تشخیص داده شده
    (x,y,w,h) = cv2.boundingRect(contour) #تعیین موقعیت محرک
    if cv2.contourArea(contour) > motion_threshold:
        cv2.rectangle(frame1, (x, y), (x + w, y + h), (255, 255, 0), 1)
        display_screen = find_screen()

از تابع find_screen () برای یافتن محل فعالیت در چهار دوربین استفاده می شود.

def find_screen():
    if (x < cam_width):
        if (y < cam_height):
            screen = frame1[0:cam_height, 0:cam_width]
            print("Activity in cam screen 1")
        else:
            screen = frame1[cam_height:cam_height*2, :cam_width]
            print("Activity in cam screen 2")
    else:
        if (y < cam_height):
            screen = frame1[:cam_height, cam_width:cam_width*2]
            print("Activity in cam screen 3")
        else:
            screen = frame1[cam_height:cam_height*2, cam_width:cam_width*2]
            print("Activity in cam screen 4")
    return (screen)

تنظیم هشدار برای تشخیص حرکت

اضافه کردن یک هشدار بعد از پیدا کردن محرک بسیار ساده است. ما یک بازر را به پین GPIO 3 رزبری پای متصل خواهیم کرد. دستور if بررسی میکند که آیا محرک تشخیص داده شده است یا خیر. در صورت تشخیص مقدار متغیر trig_alarm را افزایش خواهد داد.

ما در اینجا هشدار را برای تصویر 3 تنظیم کرده ایم. شما میتوانید صفحه را تغییر دهید یا همه صفحه ها را تنظیم کنید.

         if ((x>cam_width) and (y<cam_height)): #screen 3
                trig_alarm+=1
            else:
                trig_alarm =0

اگر مقدار trig_alarm به بیش از 3 برسد ، یک بار بوق می زند. دلیل این شمارش این است که گاهی اوقات سایه ها یا پرندگان باعث فعال شدن میشوند، بنابراین این شمارش درصد خطای پروژه را کاهش میدهد.

    if (trig_alarm>=3):#شمارش برای 3 بار
        #Beep the Buzzer
        GPIO.output(BUZZER,1)
        time.sleep(0.02)
        GPIO.output (BUZZER,0)
        trig_alarm =0

نظارت بر دما و کاربرد CPU

سیستم تشخیص حرکت اغلب به صورت 24 ساعته فعال است بنابراین میتواند باعث داغ شدن بیش از حد رزبری پای شود. بنابراین میتوانیم مقادیر مورد نیاز (دما و میزان استفاده از پردازنده) را در نمایشگر نشان دهیم. این اطلاعات با استفاده از کتابخانه gpiozero بدست می آیند.

cpu = CPUTemperature()
    load = LoadAverage()
    cpu_temperature = str((cpu.temperature)//1)
    load_average = str(load.load_average)
    #print (cpu.temperature)
    #print(load.load_average)
    cv2.putText(display_screen, cpu_temperature, (250,250), cv2.FONT_HERSHEY_SIMPLEX, 0.4, (0,0,255), 1)
    cv2.putText(display_screen, load_average, (300,250), cv2.FONT_HERSHEY_SIMPLEX, 0.4, (0,255,0), 2)

فیلم تشخیص حرکت دوربین مداربسته با رزبری پای

این پروژه برای روز های متوالی تست شده است و خوشبختانه مشکلی نداشته است. اگر قصد دارید این پروژه را به صورت مداوم فعال نگه دارید، اکیدا پیشنهاد میشود از پوشش مناسب یا فن های خنک کننده استفاده کنید. همچنین اگر در مکانی هستید که قطع برق مکررا اتفاق می افتد، میتوانید از یک سیستم برق اضطراری استفاده کنید. فیلم زیر شما را با نحوه کار این پروژه آشنا میکند.

دانلود فیلم تشخیص حرکت دوربین مداربسته

موارد موجود در فایل : سورس کامل

پروژه ها رایگان هستند. برای دانلود فایل های پروژه باید در سایت عضو باشید. ثبت نام / ورود

نظرتان را در مورد این مطلب با ستاره دادن اعلام کنید
امیدوارم این مطلب برای شما مفید بوده باشد. نظرات ، مشکلات و پیشنهادات خود را در پایین صفحه اعلام کنید
محمد رحیمی

محمد رحیمی

محمد رحیمی هستم. سعی میکنم در آیرنکس مطالب مفید را قرار دهم. مالکیتی بر مطالب ارائه شده ندارم. اکثر فعالیت بنده در زمینه ترجمه است. (در خصوص سوال در مورد این مطلب از قسمت نظرات همین مطلب اقدام کنید)

دیدگاهتان را بنویسید

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *