第1步:主要項(xiàng)目必需
Raspberry Pi攝像機(jī)
繼電器
555計(jì)時(shí)器。..。(如果您的555計(jì)時(shí)器未到達(dá),則為arduino和另一個(gè)繼電器)
電磁閥
灑水器
電子產(chǎn)品的某種外殼
愿意用6噸大錘打一個(gè)隱喻釘子
分辨率很低的相機(jī)你幾乎看不到水,但仍然可以看到貓跑來(lái)掩護(hù)
第2步:系統(tǒng)
1,Pi相機(jī)檢測(cè)到一個(gè)貓大小的物體移動(dòng)幾個(gè)相機(jī)幀(下一步驟中已經(jīng)開(kāi)始)
2,Pi啟動(dòng)噴水器
3,Cat跑步封面
4,視頻自動(dòng)上傳到y(tǒng)outube以便查看樂(lè)趣
第3步:編碼時(shí)間
使用openCV使用幀減法,您可以找到隨時(shí)間變化的幀的區(qū)域,使用一些漂亮的函數(shù),您可以確定這些變化有多大以及它們是否會(huì)持續(xù)存在,最重要的是找出它們是否是貓大小。
有相當(dāng)?shù)腶f關(guān)于幀減法的新教程,如果你進(jìn)行快速谷歌搜索,會(huì)詳細(xì)介紹。
代碼工作原理概述
1,相機(jī)不斷拍攝幀并將它們與最后
2,如果檢測(cè)到貓大小的形狀,則注意到
3,如果貓大小的變化持續(xù)超過(guò)4幀,則pi使用其GPIO為繼電器供電以啟動(dòng)arduino
4,arduino發(fā)送信號(hào)給第二個(gè)繼電器供電5秒鐘,激活電磁閥
5,電磁閥通電時(shí)允許水進(jìn)入噴水器
6,當(dāng)噴水器處于活動(dòng)狀態(tài)時(shí),攝像頭停止檢測(cè)并記錄視頻
7,視頻上傳到Y(jié)outube
8,靜止圖像上傳到保管箱以進(jìn)行微調(diào)系統(tǒng)
注意 - 為什么我最終使用2個(gè)繼電器和一個(gè)arduino打開(kāi)電磁閥5秒鐘。..。..。
1,pi錄制視頻時(shí)pi不能啟動(dòng)和停止電磁閥scrips暫停直到視頻結(jié)束,因此需要arduino(或555計(jì)時(shí)器)允許當(dāng)視頻仍在錄制時(shí),電磁鐵打開(kāi)和關(guān)閉獨(dú)立于腳本。
2,第一個(gè)繼電器和arduino可以用555定時(shí)器替換,但是沒(méi)有及時(shí)發(fā)布這個(gè)項(xiàng)目,555將節(jié)省大量的時(shí)間和金錢(qián)和步驟。
3,pi不能直接觸發(fā)螺線管,因?yàn)镻i GPIO工作在3.3v和51mA最大值,螺線管需要5V和更多觸發(fā)時(shí)不超過(guò)51mA。
4,可以裁剪每個(gè)幀以去除不需要的區(qū)域中的運(yùn)動(dòng)檢測(cè),例如neigbors garden。如果不這樣做會(huì)導(dǎo)致鄰居給你的花園帶來(lái)困惑的看法,因?yàn)槊看嗡脒M(jìn)入他的棚子時(shí)灑水器就會(huì)熄火。
5,我可能錯(cuò)過(guò)了一些明顯的東西,浪費(fèi)了我的時(shí)間來(lái)設(shè)置它像這樣。
以下代碼
import cv2
import numpy as np
import argparse #cat
import time
import RPi.GPIO as GPIO
import os
import dropbox
from picamera.array import PiRGBArray
from picamera import PiCamera
#------------------------------------------------Upload to youtube---------------------------------------
def HDtoYoutube():
ctime = time.strftime(“_%H-%M-%S”)
cdate = time.strftime(“_%d-%m-%Y”)
vidname = ctime + cdate
#Trigger relay
GPIO.output(11,True)
time.sleep(.5)
GPIO.output(11,F(xiàn)alse)
print(“Taking Video”)
try:
#Take Video
os.system(‘raspivid -w 1640 -h 922 -o vid{0}.h264 -t 15000’.format(vidname))
#Upload to youtube
print(“Uploading to YouTube”)
os.system(‘sudo youtube-upload --title=“Cat Got Wet {0}” --client-secrets=client_secret.json vid{0}.h264’.format(vidname))
#Remove video file when done
os.remove(‘vid{0}.h264’.format(vidname))
print(“Video uploaded and removed from Pi”)
except:
pass
#------------------------------------------------Stills to dropbox---------------------------------------
def StillsToDropbox():
print(“Uploading Still To Dropbox Function”)
access_token = ‘Ah ah ah, you didn’t say the magic word.。.Ah ah ah, you didn‘t say the magic word’
ctime = time.strftime(“%H:%M:%S”)
cdate = time.strftime(“%d-%m-%Y”)
try:
filename = “/Motion/{0}/DetectedAt_{1}.jpg”.format(cdate, ctime)
print(filename)
client = dropbox.client.DropboxClient(access_token)
image = open(“ToDropbox.jpg”, ‘rb’)
client.put_file(filename, image)
image.close()
os.remove(“ToDropbox.jpg”)
except:
pass
#------------------------------------------------Detect motion-----------------------------------------
def DetectMotion():
#Define vars
min_area = 400
tolarance = 25 #change in pixel
bluramount = 21
timetoforget = 0.5
kernel = np.ones((5,5),np.uint8) #used for dialate
MotionCounter = 0
MinTargetArea = 600 #smallest size to detect
MaxTargetArea = 5000 #Largest size to detect
now = time.time()
then = time.time()
#initialise camera
camera = PiCamera()
camera.resolution = (640,480)
camera.framerate = 10
rawCapture = PiRGBArray(camera, size=(640,480))
#warmup camera
time.sleep(1)
#Grab first frame & prep it to go into cv2.acumulate weight
camera.capture(rawCapture, format=“bgr”)
avg = rawCapture.array
#Crop out unwanted region
PolyCrop = np.array( [[[362,480],[613,365],[628,161],[498,0],[640,0],[640,480]]], dtype=np.int32 )
cv2.fillPoly(avg, PolyCrop, 0,0,0)
#Process image
avg = cv2.cvtColor(avg, cv2.COLOR_BGR2GRAY)
avg = cv2.GaussianBlur(avg, (bluramount, bluramount), 0)
avg = avg.copy().astype(“float”)
rawCapture.truncate(0)
print(“Ready to detect”)
#capture frames
for frame in camera.capture_continuous(rawCapture, format=“bgr”, use_video_port=True):
#Pause Switch
loopgo = GPIO.input(PauseNow)
#print(loopgo)
while loopgo == 0:
#print(loopgo)
loopgo = GPIO.input(PauseNow)
time.sleep(1)
#grabs raw numpy array
currentframe = frame.array
key = cv2.waitKey(1) & 0xFF
#Crop out unwanted region
cv2.fillPoly(currentframe, PolyCrop, 0,0,0)
rawCapture.truncate(0) #Clear frame buffer for next loop
currentgray = cv2.cvtColor(currentframe, cv2.COLOR_BGR2GRAY)
currentgray = cv2.GaussianBlur(currentgray, (bluramount, bluramount), 0)
#make time average frame
cv2.accumulateWeighted(currentgray, avg, timetoforget)
#get difference in frame
frameDelta = cv2.absdiff(currentgray, cv2.convertScaleAbs(avg))
thresh = cv2.threshold(frameDelta, tolarance, 255, cv2.THRESH_BINARY)[1]
#Turn to blob
thresh = cv2.dilate(thresh, kernel, iterations = 10) #dilate
thresh = cv2.morphologyEx(thresh, cv2.MORPH_CLOSE, kernel) #close holes
thresh = cv2.erode(thresh, kernel, iterations = 5) #erode
#contours
_, cnts, _= cv2.findContours(thresh.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
# loop over the contours
for c in cnts:
# if the contour is too small, ignore it
if cv2.contourArea(c) 《 min_area:
continue
# compute the bounding box for the contour, draw it on the frame,
# and update the textq
(x, y, w, h) = cv2.boundingRect(c)
#Too small : Red Box
if cv2.contourArea(c) 《 MinTargetArea:
cv2.rectangle(currentframe, (x, y), (x + w, y + h), (0, 0, 255), 2)
#MotionCounter = MotionCounter + 1 #Debug take all the pictures
print(“MotionDetected”)
#Just right : Green Box
if cv2.contourArea(c) 》= MinTargetArea and cv2.contourArea(c) 《= MaxTargetArea:
cv2.rectangle(currentframe, (x, y), (x + w, y + h), (0, 255, 0), 2)
MotionCounter = MotionCounter + 1 #Debug take all the pictures
print(“MotionDetected”)
#Too big : Blue Box
if cv2.contourArea(c) 》 MaxTargetArea:
cv2.rectangle(currentframe, (x, y), (x + w, y + h), (255, 0, 0), 2)
#MotionCounter = MotionCounter + 1 #Debug take all the pictures
print(“MotionDetected”)
#Keep now up to date
now = time.time()
#MotionCounterTimer
if (MotionCounter 》 0):
if (now - then 》 10):
MotionCounter = 0
then = time.time()
#Break loop on pressing Q
if key == ord(“q”):
break
#If motion persists save current frame and activate countermeasures
if MotionCounter 》= 4:
MotionCounter = 0
cv2.imwrite(‘ToDropbox.jpg’, currentframe)
camera.close()
return True
#------------------------------------------------Main---------------------------------------
try:
#Set Pins
GPIO.setmode(GPIO.BOARD)
PauseNow=12
GPIO.setup(11,GPIO.OUT)
GPIO.setup(PauseNow,GPIO.IN,pull_up_down=GPIO.PUD_UP)
while True:
MotionDetected = False
MotionDetected = DetectMotion()
if MotionDetected == True:
HDtoYoutube()
StillsToDropbox()
except KeyboardInterrupt:
print(“Keyboard Interupt”)
except:
print(“Other Error”)
finally:
GPIO.cleanup()
#HowToTriggerRealProgrammersWithBadCode
第4步:將它放在一起
將電器塞入防水外殼,將物品擰入墻壁并使用大量膠帶和熱膠
第5步:結(jié)果
什么時(shí)候有效
第6步:誤報(bào)
如果沒(méi)有,它會(huì)噴射貓影,你的妻子和你的女兒。
Pro -tip - 在門(mén)旁邊放一個(gè)開(kāi)關(guān),暫停運(yùn)動(dòng)檢測(cè)程序。..。.然后忘記使用它并在放入垃圾箱時(shí)弄濕。
-
計(jì)算機(jī)視覺(jué)
+關(guān)注
關(guān)注
9文章
1709瀏覽量
46786 -
智能灑水器
+關(guān)注
關(guān)注
0文章
2瀏覽量
1133
發(fā)布評(píng)論請(qǐng)先 登錄
AR和VR中的計(jì)算機(jī)視覺(jué)

量子計(jì)算機(jī)與普通計(jì)算機(jī)工作原理的區(qū)別

【小白入門(mén)必看】一文讀懂深度學(xué)習(xí)計(jì)算機(jī)視覺(jué)技術(shù)及學(xué)習(xí)路線

計(jì)算機(jī)接口位于什么之間
計(jì)算機(jī)存儲(chǔ)系統(tǒng)的構(gòu)成
計(jì)算機(jī)存儲(chǔ)器的分類(lèi)及其區(qū)別
簡(jiǎn)述計(jì)算機(jī)總線的分類(lèi)
晶體管計(jì)算機(jī)和電子管計(jì)算機(jī)有什么區(qū)別
微處理器如何控制計(jì)算機(jī)系統(tǒng)
計(jì)算機(jī)視覺(jué)有哪些優(yōu)缺點(diǎn)
圖像處理器與計(jì)算機(jī)視覺(jué)有什么關(guān)系和區(qū)別
計(jì)算機(jī)視覺(jué)中的圖像融合

地平線科研論文入選國(guó)際計(jì)算機(jī)視覺(jué)頂會(huì)ECCV 2024

評(píng)論