This commit is contained in:
Gorkem 2020-11-05 14:52:54 +03:00
parent 3664e9b9fb
commit 2571334bb2

191
hauntedTV.py Normal file
View File

@ -0,0 +1,191 @@
import cv2
import time
import numpy as np
import sys
import RPi.GPIO as GPIO
#timers
GPIO.setwarnings(False)
GPIO.setmode(GPIO.BOARD) # Use physical pin numbering
GPIO.setup(12, GPIO.IN)# Remote Button B - Take picture
GPIO.setup(16, GPIO.IN)# Remote button D - Armed & Ready
GPIO.setup(22, GPIO.OUT)# RED
GPIO.setup(24, GPIO.OUT)# GREEN
GPIO.setup(26, GPIO.OUT)# BLUE
GPIO.setup(32, GPIO.OUT)# Relay - TV on/off
#If you want to use a custom background you can use this function to resize it.
def resize(dst,img):
width = img.shape[1]
height = img.shape[0]
dim = (width, height)
resized = cv2.resize(dst, dim, interpolation = cv2.INTER_AREA)
return resized
presenceTriggered = False
cooldown = False #cooldown state after the haunt is over
ghostVisible = False #toggles the visiblity of the ghost
GPIO.output(32, GPIO.HIGH) #Turn TV on at the beginning for setup mode.
window_name = "window"
face_cascade = cv2.CascadeClassifier('/home/pi/Documents/haarcascade_frontalface_default.xml')
eye_cascade = cv2.CascadeClassifier('haarcascade_eye.xml')
#inialize fullscreen
cv2.namedWindow(window_name, cv2.WINDOW_NORMAL)
cv2.setWindowProperty(window_name, cv2.WND_PROP_FULLSCREEN, cv2.WINDOW_FULLSCREEN)
#capture video from the camera if you want to test this on your computer, change 0 with 1
cam = cv2.VideoCapture(0)
#custom resolution for CRT TV
cam.set(3,768)
cam.set(4,576)
success, ref_img = cam.read() #reference image taken for background removal
success2, bg = cam.read()
success3, bg2 = cam.read()
flag = 0
#star the timers
coolDownStart = time.time() #this will reset after the haunt is done.
faceTimeStart = time.time() #the time it takes to detect a new face.
ghostTime = time.time()
faceFreqCounter = 0 #face frequency counter to filter out false positives
while True:
ret, img = cam.read()
if ret:
img=cv2.flip(img,0) #flips the image vertically
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
detected = face_cascade.detectMultiScale(gray, 1.3, 5)
#erase the '#' below if you want to detect eyes instead of faces
#detected = eye_cascade.detectMultiScale(gray)
#If the setup is armed, execute facedetection.
if flag==3:
if not cooldown: #the cooldown timer prevents the facedetection from running
for (x,y,w,h) in detected:
#draw rectangles around faces/eyes for debugging
#cv2.rectangle(img,(x,y),(x+w,y+h),(255,0,0),2)
faceTimeEnd = time.time()
elapsedFaceTime = faceTimeEnd - faceTimeStart
if (elapsedFaceTime<1):
faceFreqCounter+=1
print(faceFreqCounter)
if (elapsedFaceTime>5):
faceFreqCounter=0
faceTimeStart = time.time()
faceDetectionElapsed=time.time()- faceTimeStart
if(faceFreqCounter>5) & (not ghostVisible) & (not presenceTriggered):
GPIO.output(32, GPIO.HIGH)
if(faceFreqCounter>25) & (faceDetectionElapsed>0.5) & (not ghostVisible):
ghostVisible = True
faceFreqCounter=0
bg = bgHaunted
if(ghostVisible & (faceFreqCounter>10) & (faceDetectionElapsed>0.5)) & (not presenceTriggered):
print("NO GHOST")
ghostTime = time.time()
ghostVisible = False
faceFreqCounter=0
presenceTriggered = True
bg=bg2
end2 = time.time()
elapsedTime2 = end2 - ghostTime
print(elapsedTime2)
if (elapsedTime2>5) and presenceTriggered:
GPIO.output(32, GPIO.LOW)
presenceTriggered = False
cooldown = True
if (elapsedTime2>20) and cooldown:
print("cooldown done")
faceFreqCounter=0
cooldown = False
#background removal based on https://github.com/misbah4064/backgroundRemoval
#success, img = cam.read()
if flag==0:
ref_img = img
flag=1
if flag==2:
success3, bgHaunted = cam.read()
flag=1
# create a mask
diff1=cv2.subtract(img,ref_img)
diff2=cv2.subtract(ref_img,img)
diff = diff1+diff2
#orig value =13
diff[abs(diff)<20.0]=0
gray = cv2.cvtColor(diff.astype(np.uint8), cv2.COLOR_BGR2GRAY)
gray[np.abs(gray) < 10] = 0
fgmask = gray.astype(np.uint8)
fgmask[fgmask>0]=255
#invert the mask
fgmask_inv = cv2.bitwise_not(fgmask)
#use the masks to extract the relevant parts from FG and BG
fgimg = cv2.bitwise_and(img,img,mask = fgmask)
bgimg = cv2.bitwise_and(bg,bg,mask = fgmask_inv)
#combine both the BG and the FG images
dst = cv2.add(fgimg,bgimg)
dst=cv2.flip(dst, 0)
cv2.imshow(window_name,dst)
key = cv2.waitKey(5) & 0xFF
if ord('q') == key:
break
if ord('a') == key or (GPIO.input(16) == GPIO.HIGH):
flag = 3
print("Setup armed and ready!")
GPIO.output(24, GPIO.LOW)
GPIO.output(22, GPIO.HIGH) #turn on TV
GPIO.output(32, GPIO.LOW)
if (ord('h') == key) or (GPIO.input(12) == GPIO.HIGH):
flag = 2
print("Haunted Picture Taken!")
GPIO.output(24, GPIO.HIGH)
GPIO.output(22, GPIO.LOW)
elif ord('d') == key:
flag = 1
print("Background Captured")
elif ord('r') == key:
flag = 0
print("Ready to Capture new Background")
elif ord('t') == key:
bg = bgHaunted
#ref_img = bg
print("Image is now haunted!")
GPIO.cleanup()
cv2.destroyAllWindows()
cam.release()