I have this code that performs the mouse functions using eyes and other facial gestures with opencv and dlib. I am running this code using a button click from a tkinter window. When this code starts to run, that tkinter window freezes (i.e, I cannot click any other button from that).
Is there a way that I can make the frame used by opencv a Top level, like top level frames in tkinter so that it doesn't freezes any other frames, or how can I replace opencv frame with Tkinter toplevel frame.
P.S: I have been on it for two days, literally tried anything I can find on the internet and can't seem to find a solution.
_, frame = vid.read()
frame = cv2.flip(frame, 1)
frame = imutils.resize(frame, width=cam_w, height=cam_h)
gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
This is the part where changes will be made I guess. Full code is shared below.
from imutils import face_utils
from utils import *
import numpy as np
import pyautogui as pag
import imutils
import dlib
import cv2
# Thresholds and consecutive frame length for triggering the mouse action.
MOUTH_AR_THRESH = 0.3
MOUTH_AR_CONSECUTIVE_FRAMES = 3
EYE_AR_THRESH = 0.20
EYE_AR_CONSECUTIVE_FRAMES = 5
WINK_AR_DIFF_THRESH = 0.001
WINK_AR_CLOSE_THRESH = 0.2
WINK_CONSECUTIVE_FRAMES = 4
# Initialize the frame counters for each action as well as
# booleans used to indicate if action is performed or not
MOUTH_COUNTER = 0
EYE_COUNTER = 0
WINK_COUNTER = 0
INPUT_MODE = False
EYE_CLICK = False
LEFT_WINK = False
RIGHT_WINK = False
SCROLL_MODE = False
ANCHOR_POINT = (0, 0)
WHITE_COLOR = (255, 255, 255)
YELLOW_COLOR = (0, 255, 255)
RED_COLOR = (0, 0, 255)
GREEN_COLOR = (0, 255, 0)
BLUE_COLOR = (255, 0, 0)
BLACK_COLOR = (0, 0, 0)
# Initialize Dlib's face detector (HOG-based) and then create
# the facial landmark predictor
shape_predictor = "model/shape_predictor_68_face_landmarks.dat"
detector = dlib.get_frontal_face_detector()
predictor = dlib.shape_predictor(shape_predictor)
# Grab the indexes of the facial landmarks for the left and
# right eye, nose and mouth respectively
(lStart, lEnd) = face_utils.FACIAL_LANDMARKS_IDXS["left_eye"]
(rStart, rEnd) = face_utils.FACIAL_LANDMARKS_IDXS["right_eye"]
(nStart, nEnd) = face_utils.FACIAL_LANDMARKS_IDXS["nose"]
(mStart, mEnd) = face_utils.FACIAL_LANDMARKS_IDXS["mouth"]
# Video capture
vid = cv2.VideoCapture(0)
resolution_w = 1366
resolution_h = 768
cam_w = 640
cam_h = 480
unit_w = resolution_w / cam_w
unit_h = resolution_h / cam_h
while True:
# Grab the frame from the threaded video file stream, resize
# it, and convert it to grayscale
# channels)
_, frame = vid.read()
frame = cv2.flip(frame, 1)
frame = imutils.resize(frame, width=cam_w, height=cam_h)
gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
# Detect faces in the grayscale frame
rects = detector(gray, 0)
# Loop over the face detections
if len(rects) > 0:
rect = rects[0]
else:
cv2.imshow("Frame", frame)
key = cv2.waitKey(1) & 0xFF
continue
# Determine the facial landmarks for the face region, then
# convert the facial landmark (x, y)-coordinates to a NumPy
# array
shape = predictor(gray, rect)
shape = face_utils.shape_to_np(shape)
# Extract the left and right eye coordinates, then use the
# coordinates to compute the eye aspect ratio for both eyes
mouth = shape[mStart:mEnd]
leftEye = shape[lStart:lEnd]
rightEye = shape[rStart:rEnd]
nose = shape[nStart:nEnd]
# Because I flipped the frame, left is right, right is left.
temp = leftEye
leftEye = rightEye
rightEye = temp
# Average the mouth aspect ratio together for both eyes
mar = mouth_aspect_ratio(mouth)
leftEAR = eye_aspect_ratio(leftEye)
rightEAR = eye_aspect_ratio(rightEye)
ear = (leftEAR + rightEAR) / 2.0
diff_ear = np.abs(leftEAR - rightEAR)
nose_point = (nose[3, 0], nose[3, 1])
# Compute the convex hull for the left and right eye, then
# visualize each of the eyes
mouthHull = cv2.convexHull(mouth)
leftEyeHull = cv2.convexHull(leftEye)
rightEyeHull = cv2.convexHull(rightEye)
cv2.drawContours(frame, [mouthHull], -1, YELLOW_COLOR, 1)
cv2.drawContours(frame, [leftEyeHull], -1, YELLOW_COLOR, 1)
cv2.drawContours(frame, [rightEyeHull], -1, YELLOW_COLOR, 1)
for (x, y) in np.concatenate((mouth, leftEye, rightEye), axis=0):
cv2.circle(frame, (x, y), 2, GREEN_COLOR, -1)
# Check to see if the eye aspect ratio is below the blink
# threshold, and if so, increment the blink frame counter
if diff_ear > WINK_AR_DIFF_THRESH:
if leftEAR < rightEAR:
if leftEAR < EYE_AR_THRESH:
WINK_COUNTER += 1
if WINK_COUNTER > WINK_CONSECUTIVE_FRAMES:
pag.click(button='left')
WINK_COUNTER = 0
elif leftEAR > rightEAR:
if rightEAR < EYE_AR_THRESH:
WINK_COUNTER += 1
if WINK_COUNTER > WINK_CONSECUTIVE_FRAMES:
pag.click(button='right')
WINK_COUNTER = 0
else:
WINK_COUNTER = 0
else:
if ear <= EYE_AR_THRESH:
EYE_COUNTER += 1
if EYE_COUNTER > EYE_AR_CONSECUTIVE_FRAMES:
SCROLL_MODE = not SCROLL_MODE
# INPUT_MODE = not INPUT_MODE
EYE_COUNTER = 0
# nose point to draw a bounding box around it
else:
EYE_COUNTER = 0
WINK_COUNTER = 0
if mar > MOUTH_AR_THRESH:
MOUTH_COUNTER += 1
if MOUTH_COUNTER >= MOUTH_AR_CONSECUTIVE_FRAMES:
# if the alarm is not on, turn it on
INPUT_MODE = not INPUT_MODE
# SCROLL_MODE = not SCROLL_MODE
MOUTH_COUNTER = 0
ANCHOR_POINT = nose_point
else:
MOUTH_COUNTER = 0
if INPUT_MODE:
cv2.putText(frame, "READING INPUT!", (10, 30), cv2.FONT_HERSHEY_SIMPLEX, 0.7, RED_COLOR, 2)
x, y = ANCHOR_POINT
nx, ny = nose_point
w, h = 60, 35
multiple = 1
cv2.rectangle(frame, (x - w, y - h), (x + w, y + h), GREEN_COLOR, 2)
cv2.line(frame, ANCHOR_POINT, nose_point, BLUE_COLOR, 2)
dir = direction(nose_point, ANCHOR_POINT, w, h)
cv2.putText(frame, dir.upper(), (10, 90), cv2.FONT_HERSHEY_SIMPLEX, 0.7, RED_COLOR, 2)
drag = 18
if dir == 'right':
pag.moveRel(drag, 0)
elif dir == 'left':
pag.moveRel(-drag, 0)
elif dir == 'up':
if SCROLL_MODE:
pag.scroll(40)
else:
pag.moveRel(0, -drag)
elif dir == 'down':
if SCROLL_MODE:
pag.scroll(-40)
else:
pag.moveRel(0, drag)
if SCROLL_MODE:
cv2.putText(frame, 'SCROLL MODE IS ON!', (10, 60), cv2.FONT_HERSHEY_SIMPLEX, 0.7, RED_COLOR, 2)
# Show the frame
cv2.imshow("Frame", frame)
key = cv2.waitKey(1) & 0xFF
# If the `Esc` key was pressed, break from the loop
if key == 27:
break
# Do a bit of cleanup
cv2.destroyAllWindows()
vid.release()
Related
from scipy.spatial import distance as dist
from imutils import face_utils
import imutils
import dlib
import cv2
import winsound
from tkinter import Tk, Button
frequency = 2500
duration = 5000
def eyeAspectRatio(eye):
A = dist.euclidean(eye[1], eye[5])
B = dist.euclidean(eye[2], eye[4])
C = dist.euclidean(eye[0], eye[3])
ear = (A + B) / (2.0 * C)
return ear
def run():
count = 0
earThresh = 0.3 #distance between vertical eye coordinate Threshold
earFrames = 48 #consecutive frames for eye closure
#shapePredictor = "C:\\Users\\ATUL GHUMADE\\Downloads\\code\\code\\shape_predictor_68_face_landmarks.dat"
cam = cv2.VideoCapture(0)
detector = dlib.get_frontal_face_detector()
predictor = dlib.shape_predictor("shape_predictor_68_face_landmarks.dat")
#get the coord of left & right eye
(lStart, lEnd) = face_utils.FACIAL_LANDMARKS_IDXS["left_eye"]
(rStart, rEnd) = face_utils.FACIAL_LANDMARKS_IDXS["right_eye"]
while True:
_, frame = cam.read()
frame = imutils.resize(frame, width=450)
gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
rects = detector(gray, 0)
for rect in rects:
shape = predictor(gray, rect)
shape = face_utils.shape_to_np(shape)
leftEye = shape[lStart:lEnd]
rightEye = shape[rStart:rEnd]
leftEAR = eyeAspectRatio(leftEye)
rightEAR = eyeAspectRatio(rightEye)
ear = (leftEAR + rightEAR) / 2.0
leftEyeHull = cv2.convexHull(leftEye)
rightEyeHull = cv2.convexHull(rightEye)
cv2.drawContours(frame, [leftEyeHull], -1, (0, 0, 255), 1)
cv2.drawContours(frame, [rightEyeHull], -1, (0, 0, 255), 1)
if ear < earThresh:
count += 1
if count >= earFrames:
cv2.putText(frame, "DROWSINESS DETECTED", (10, 30),
cv2.FONT_HERSHEY_SIMPLEX, 0.7, (0, 0, 255), 2)
winsound.Beep(frequency, duration)
else:
count = 0
cv2.imshow("Frame", frame)
key = cv2.waitKey(1) & 0xFF
if key == ord("q"):
break
cam.release()
cv2.destroyAllWindows()
'''
tk=Tk()
tk.geometry('500x500')
sub=Button(tk,text="Inspect",command=run).pack()
tk.mainloop()
'''
run()
Traceback (most recent call last):
File "C:\Users\ASUS\Desktop\Drowssiness detection - Copy\drowsiness detection\code\main.py", line 82, in
run()
File "C:\Users\ASUS\Desktop\Drowssiness detection - Copy\drowsiness detection\code\main.py", line 35, in run
frame = imutils.resize(frame, width=450)
File "C:\Users\ASUS\AppData\Local\Programs\Python\Python39\lib\site-packages\imutils\convenience.py", line 69, in resize
(h, w) = image.shape[:2]
AttributeError: 'NoneType' object has no attribute 'shape'
My opencv code is lagging in raspbpi but in pc its smooth. Can anyone help me make my hard code to a code that uses threading.
from cv2 import cv2
import numpy as np
from pyzbar.pyzbar import decode
import pickle,time
import os
import imutils
import screeninfo
from screeninfo import get_monitors
curr_path = os.getcwd()
#########models##################################################
print("Loading face detection model")
proto_path = os.path.join(curr_path, 'model', 'deploy.prototxt')
model_path = os.path.join(curr_path, 'model', 'res10_300x300_ssd_iter_140000.caffemodel')
face_detector = cv2.dnn.readNetFromCaffe(prototxt=proto_path, caffeModel=model_path)
print("Loading face recognition model")
recognition_model = os.path.join(curr_path, 'model', 'openface_nn4.small2.v1.t7')
face_recognizer = cv2.dnn.readNetFromTorch(model=recognition_model)
################pickles#########################################
recognizer = pickle.loads(open('recognizer.pickle', "rb").read())
le = pickle.loads(open('le.pickle', "rb").read())
print("Starting test video file")
#adjacents########################################################################
no_of_adjacent_prediction=0
no_face_detected=0 #to track the number of times the face is detected
prev_predicted_name='' #to keep track of the previously predicted face(w.r.t frame)
count_frames = total_no_face_detected = 0
#camera#########################################################################
font=cv2.FONT_HERSHEY_SIMPLEX
clr=(255,255,255)
cap = cv2.VideoCapture(0)
time.sleep(2)
profile = None
####TRY_COUNTS###########
MAX_TRY=3
tries=0 #
######flags############
flag = True
flag_face_recognised=False #to keep track if the user face is recognized
flag_face_not_recognised=False
#############FULLSCREEN###############
WINDOW_NAME = "Face-Rcognition and QRCODEQQQQQ"
screenid = 0
while True:
cv2.namedWindow(WINDOW_NAME, cv2.WND_PROP_FULLSCREEN)
cv2.setWindowProperty(WINDOW_NAME, cv2.WND_PROP_FULLSCREEN, cv2.WINDOW_FULLSCREEN)
ret, frame = cap.read()
screen = screeninfo.get_monitors()[screenid]
screen_width, screen_height = screen.width,screen.height
frame = cv2.flip(frame, 1)
frame_height, frame_width, _ = frame.shape
scaleWidth = float(screen_width) / float(frame_width)
scaleHeight = float(screen_height) / float(frame_height)
if (flag):
access = open("AccessCodes.txt")
for i in decode(frame):
decoded_data = i.data.decode("utf-8") # converts bytes to string value
print(decoded_data)
# Drawing polygon on frame (tilts w.r.t orientation)
pts = np.array([i.polygon], np.int32)
pts = pts.reshape((-1, 1, 2))
cv2.polylines(frame, [pts], True, (0, 255, 0), 1)
# print(pts)
# Display text
rect_pts = i.rect # using rect point as origin for text as we don't want the text to tilt with the qrcode
fontScale = 0.8
thickness = 1
# cv2.putText(frame,decoded_data,(rect_pts[0],rect_pts[1]),cv2.FONT_HERSHEY_SIMPLEX,fontScale,(255,0,0),thickness)
# print(rect_pts)
if decoded_data.lower() in access.read(): # Check private key
flag = False
tries = 0
print("QRCODE is Valid.Proceed to FaceRecog")
time_out_no_of_frames_after_qrcode = 0
else:
# print("INVALID QR CODE")
print("Invalid QRCODE")
if scaleHeight > scaleWidth:
imgScale = scaleWidth
else:
imgScale = scaleHeight
newX, newY = frame.shape[1] * imgScale, frame.shape[0] * imgScale
frame = cv2.resize(frame, (int(newX), int(newY)))
cv2.imshow(WINDOW_NAME, frame)
else:
frame = cv2.resize(frame, (int(newX), int(newY)))
(h, w) = frame.shape[:2]
image_blob = cv2.dnn.blobFromImage(cv2.resize(frame, (300, 300)), 1.0, (300, 300), (104.0, 177.0, 123.0), False, False)
face_detector.setInput(image_blob)
face_detections = face_detector.forward()
for i in range(0, face_detections.shape[2]):
confidence = face_detections[0, 0, i, 2]
if confidence > 0.90:
box = face_detections[0, 0, i, 3:7] * np.array([w, h, w, h])
(startX, startY, endX, endY) = box.astype("int")
face = frame[startY:endY, startX:endX]
(fH, fW) = face.shape[:2]
face_blob = cv2.dnn.blobFromImage(face, 1.0/255, (96, 96), (0, 0, 0), True, False)
face_recognizer.setInput(face_blob)
vec = face_recognizer.forward()
preds = recognizer.predict_proba(vec)[0]
j = np.argmax(preds)
proba = preds[j]
name = le.classes_[j]
text = "{}: {:.2f}".format(name, proba )
y = startY - 10 if startY - 10 > 10 else startY + 10
cv2.rectangle(frame, (startX, startY), (endX, endY), (0, 0, 255), 2)
cv2.putText(frame, text, (startX, y), cv2.FONT_HERSHEY_SIMPLEX, 0.65, (0, 0, 255), 2)
cv2.putText(frame, "Welcome home " + name.replace('_', ' ').title(), (160, 460), font, 0.8, clr,
thickness+3, cv2.LINE_AA)
cv2.rectangle(frame, (startX, startY), (endX, endY), (255, 255, 255), 1)
if name == decoded_data.lower():
print("Face is Recognised: "+str(no_of_adjacent_prediction))
no_of_adjacent_prediction += 1
else:
print("Face not Recognised.")
cv2.putText(frame, "Face Not Recognised", (160, 460), font, 0.8, clr, thickness, cv2.LINE_AA)
flag_face_not_recognised = True
no_of_adjacent_prediction = 0
if (no_of_adjacent_prediction > 10): # no_of_adjacent_prediction is only updated when the confidence of classification is >80
flag_face_recognised = True
no_of_adjacent_prediction = 0
no_face_detected = 0
cv2.imshow(WINDOW_NAME, frame)
if (flag_face_recognised): # if face is recognized then open the door
# arduino.write(bytes('o', 'utf-8')) #Output the given byte string over the serial port.
print("DOOR is OPEN")
time.sleep(5)
# speak("Closing door")
# arduino.write(bytes('c', 'utf-8')) #Output the given byte string over the serial port.
print("DOOR is CLOSED")
flag_face_recognised = False
flag = True # to start from qrcode
if (flag_face_not_recognised):
# speak("Face not recognised. The door will remain closed")
time.sleep(2)
flag_face_not_recognised = False
tries += 1
if (tries >= MAX_TRY):
flag = True # to start from qrcode
tries = 0
if (time_out_no_of_frames_after_qrcode >= 400):
# speak("User authentication failed due to time out")
flag = True # to start from qrcode
key = cv2.waitKey(1) & 0xFF
if key == ord('q'):
break
cv2.destroyAllWindows()
FPS PC: 20 fps
FPS RASPBERRY PI : 9 fps
i tried various opencv codes and the result is still the same. I found a solution that threading increases the fps of opencv but i do not know how to apply this to my code due the fact that i am a noob python kid. a help would be nice. I want my fps in my raspberry ranging from 15-20 instead of 9 fps.
I need to detect the high variation of the optical flow in the video. For example the crossroads. Two cars are driving and they have some value of optical flow. Next, in some time period, they have collision, so it will produce a high variation of optical flow. How to detect it?
optical flow with binarization and mask
expecting the result to fire event when the variation of the optical flow high
how to capture this event?
def label_flows(flows):
criteria = (cv.TERM_CRITERIA_EPS + cv.TERM_CRITERIA_MAX_ITER, 10, 1.0)
flags = cv.KMEANS_RANDOM_CENTERS
h, w = flows.shape[:2]
labeled_flows = []
flows = flows.reshape(h*w, -1)
comp, labels, centers = cv.kmeans(flows, 2, None, criteria, 10, flags)
n = np.sum(labels == 1)
camera_motion_label = np.argmax([labels.size-n, n])
labeled = np.uint8(255*(labels.reshape(h, w) == camera_motion_label))
return labeled
def find_target_in_labeled_flow(labeled_flow):
labeled_flow = cv2.bitwise_not(labeled_flow)
bw = 10
h, w = labeled_flow.shape[:2]
border_cut = labeled_flow[bw:h-bw, bw:w-bw]
conncomp, stats = cv2.connectedComponentsWithStats(border_cut, connectivity=8)[1:3]
target_label = np.argmax(stats[1:, cv2.CC_STAT_AREA]) + 1
img = np.zeros_like(labeled_flow)
img[bw:h-bw, bw:w-bw] = 255*(conncomp == target_label)
return img
def put_optical_flow_arrows_on_image(image, optical_flow_image, threshold=2.0, skip_amount=30):
image = image.copy()
if len(image.shape) == 2:
image = np.stack((image,)*3, axis=2)
flow_start = np.stack(np.meshgrid(range(optical_flow_image.shape[1]), range(optical_flow_image.shape[0])), 2)
flow_end = (optical_flow_image[flow_start[:,:,1],flow_start[:,:,0],:1]*3 + flow_start).astype(np.int32)
norm = np.linalg.norm(flow_end - flow_start, axis=2)
norm[norm < threshold] = 0
nz = np.nonzero(norm)
for i in range(0, len(nz[0]), skip_amount):
y, x = nz[0][i], nz[1][i]
cv.arrowedLine(image,
pt1=tuple(flow_start[y,x]),
pt2=tuple(flow_end[y,x]),
color=(0, 255, 0),
thickness=1,
tipLength=.2)
return image
if __name__ =='__main__':
cap = cv.VideoCapture("video.mp4")
ret, first_frame = cap.read()
prev_gray = cv.cvtColor(first_frame, cv.COLOR_BGR2GRAY)
mask = np.zeros_like(first_frame)
mask[..., 1] = 255
cv.namedWindow('input',cv.WINDOW_NORMAL)
cv.namedWindow('binarized',cv.WINDOW_NORMAL)
cv.namedWindow('dense_optical_flow',cv.WINDOW_NORMAL)
cv.namedWindow('color', cv.WINDOW_NORMAL)
while(cap.isOpened()):
ret, frame = cap.read()
gray = cv.cvtColor(frame, cv.COLOR_BGR2GRAY)
flow = cv.calcOpticalFlowFarneback(prev_gray, gray, None, 0.5, 3, 15, 3, 5, 1.2, 0)
magnitude, angle = cv.cartToPolar(flow[..., 0], flow[..., 1])
mask[..., 0] = angle * 180 / np.pi / 2
mask[..., 2] = cv.normalize(magnitude, None, 0, 255, cv.NORM_MINMAX)
rgb = cv.cvtColor(mask, cv.COLOR_HSV2BGR)
binary_flow = label_flows(flow)
optical_flow_arrows = put_optical_flow_arrows_on_image(gray, flow)
hsv = cv.cvtColor(optical_flow_arrows, cv.COLOR_BGR2HSV)
mask_green = cv.inRange(hsv, (36, 25, 25), (70, 255,255))
imask = mask_green>0
green = np.zeros_like(optical_flow_arrows, np.uint8)
green[imask] = optical_flow_arrows[imask]
# Here I need to calculate the variation of the optical flow
# Any ideas about how to do it?
cv.imshow("binarized", binary_flow)
cv.imshow("dense_optical_flow", optical_flow_arrows)
cv.imshow('color', green)
prev_gray = gray
if cv.waitKey(1) & 0xFF == ord('q'):
break
cap.release()
cv.destroyAllWindows()
I wish to alter this code in order to track a singular large object in motion, i.e. a person, when I run the code as is, the display will track a person as multiple objects rather than as one singular object.
Ignoring the firebase, I want to draw the rectangle around the entire object, rather than parts of the object.
Also, I wish to change the orientation of the lines set on the display from horizontal to vertical, please?
import datetime
import math
import cv2
import numpy as np
from firebase import firebase
# global variables
width = 0
height = 0
EntranceCounter = 0
ExitCounter = 0
min_area = 3000 # Adjust ths value according to your usage
_threshold = 70 # Adjust ths value according to your usage
OffsetRefLines = 150 # Adjust ths value according to your usage
# Check if an object in entering in monitored zone
def check_entrance_line_crossing(y, coor_y_entrance, coor_y_exit):
abs_distance = abs(y - coor_y_entrance)
if ((abs_distance <= 2) and (y < coor_y_exit)):
return 1
else:
return 0
# Check if an object in exitting from monitored zone
def check_exit_line_crossing(y, coor_y_entrance, coor_y_exit):
abs_distance = abs(y - coor_y_exit)
if ((abs_distance <= 2) and (y > coor_y_entrance)):
return 1
else:
return 0
camera = cv2.VideoCapture(0)
# force 640x480 webcam resolution
camera.set(3, 640)
camera.set(4, 480)
ReferenceFrame = None
# Frames may discard while adjusting to light
for i in range(0, 20):
(grabbed, Frame) = camera.read()
while True:
(grabbed, Frame) = camera.read()
height = np.size(Frame, 0)
width = np.size(Frame, 1)
# if cannot grab a frame, this program ends here.
if not grabbed:
break
# gray-scale and Gaussian blur filter applying
GrayFrame = cv2.cvtColor(Frame, cv2.COLOR_BGR2GRAY)
GrayFrame = cv2.GaussianBlur(GrayFrame, (21, 21), 0)
if ReferenceFrame is None:
ReferenceFrame = GrayFrame
continue
# Background subtraction and image manipulation
FrameDelta = cv2.absdiff(ReferenceFrame, GrayFrame)
FrameThresh = cv2.threshold(FrameDelta, _threshold, 255, cv2.THRESH_BINARY)[1]
# Dilate image and find all the contours
FrameThresh = cv2.dilate(FrameThresh, None, iterations=2)
_, cnts, _ = cv2.findContours(FrameThresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
qtty_of_count = 0
# plot reference lines (entrance and exit lines)
coor_y_entrance = (height // 2) - OffsetRefLines
coor_y_exit = (height // 2) + OffsetRefLines
cv2.line(Frame, (0, coor_y_entrance), (width, coor_y_entrance), (255, 0, 0), 2)
cv2.line(Frame, (0, coor_y_exit), (width, coor_y_exit), (0, 0, 255), 2)
# check all found count
for c in cnts:
# if a contour has small area, it'll be ignored
if cv2.contourArea(c) < min_area:
continue
qtty_of_count = qtty_of_count + 1
app = firebase.FirebaseApplication('https://finalyearproj-caa49.firebaseio.com/', None)
## result = app.post('/people', {'count': qtty_of_count})##
update = app.put('/people', "count", qtty_of_count)
print("Updated value in FB" + str(update))
# draw an rectangle "around" the object
(x, y, w, h) = cv2.boundingRect(c)
cv2.rectangle(Frame, (x, y), (x + w, y + h), (0, 255, 0), 2)
# find object's centroid
coor_x_centroid = (x + x + w) // 2
coor_y_centroid = (y + y + h) // 2
ObjectCentroid = (coor_x_centroid, coor_y_centroid)
cv2.circle(Frame, ObjectCentroid, 1, (0, 0, 0), 5)
if (check_entrance_line_crossing(coor_y_centroid, coor_y_entrance, coor_y_exit)):
EntranceCounter += 1
if (check_exit_line_crossing(coor_y_centroid, coor_y_entrance, coor_y_exit)):
ExitCounter += 1
print("Total countours found: " + str(qtty_of_count))
# Write entrance and exit counter values on frame and shows it
cv2.putText(Frame, "Entrances: {}".format(str(EntranceCounter)), (10, 50),
cv2.FONT_HERSHEY_SIMPLEX, 0.5, (250, 0, 1), 2)
cv2.putText(Frame, "Exits: {}".format(str(ExitCounter)), (10, 70),
cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 0, 255), 2)
cv2.imshow("Original Frame", Frame)
cv2.waitKey(1)
# cleanup the camera and close any open windows
camera.release()
cv2.destroyAllWindows()
The program is saying Process finished with exit code 0 but i am not getting any output. I am using Python version 2.7 and the program's job is to detect free parking slots in a car park. It also has pedestrian detection. Any help will be very much appreciated please i badly need this code to work. Thanks
Here is the link to the source code, along with a video link of how it works
https://github.com/ankit1khare/ComputerVision
DESIRED OUTPUT: The program should open the input video and draw the parking overlay on top of the video.
Here are the codes for the main program
import yaml
import numpy as np
import cv2
# path references
fn = "Khare_testvideo_01.mp4" #3
#fn = "datasets\parkinglot_1_720p.mp4"
#fn = "datasets\street_high_360p.mp4"
fn_yaml = "Khare_yml_01.yml"
fn_out = "Khare_outputvideo_01.avi"
cascade_src = 'Khare_classifier_02.xml'
car_cascade = cv2.CascadeClassifier(cascade_src)
global_str = "Last change at: "
change_pos = 0.00
dict = {
'text_overlay': True,
'parking_overlay': True,
'parking_id_overlay': True,
'parking_detection': True,
'motion_detection': True,
'pedestrian_detection': False, # takes a lot of processing power
'min_area_motion_contour': 500, # area given to detect motion
'park_laplacian_th': 2.8,
'park_sec_to_wait': 1, # 4 wait time for changing the status of a region
'start_frame': 0, # begin frame from specific frame number
'show_ids': True, # shows id on each region
'classifier_used': True,
'save_video': True
}
# Set from video
cap = cv2.VideoCapture(fn)
print("video found")
video_info = { 'fps': cap.get(cv2.CAP_PROP_FPS),
'width': int(cap.get(cv2.CAP_PROP_FRAME_WIDTH)*0.6),
'height': int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT)*0.6),
'fourcc': cap.get(cv2.CAP_PROP_FOURCC),
'num_of_frames': int(cap.get(cv2.CAP_PROP_FRAME_COUNT))}
cap.set(cv2.CAP_PROP_POS_FRAMES, dict['start_frame']) # jump to frame number specified
def run_classifier(img, id):
# gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
cars = car_cascade.detectMultiScale(img, 1.1, 1)
if cars == ():
return False
else:
# parking_status[id] = False
return True
# Define the codec and create VideoWriter object
if dict['save_video']:
fourcc = cv2.VideoWriter_fourcc('X','V','I','D') # options: ('P','I','M','1'), ('D','I','V','X'), ('M','J','P','G'), ('X','V','I','D')
out = cv2.VideoWriter(fn_out, -1, 25.0,(video_info['width'], video_info['height']))
print("save video -- out w * H")
# initialize the HOG descriptor/person detector. Take a lot of processing power.
if dict['pedestrian_detection']:
hog = cv2.HOGDescriptor()
hog.setSVMDetector(cv2.HOGDescriptor_getDefaultPeopleDetector())
# Use Background subtraction
if dict['motion_detection']:
fgbg = cv2.createBackgroundSubtractorMOG2(history=300, varThreshold=16, detectShadows=True)
# Read YAML data (parking space polygons)
with open(fn_yaml, 'r') as stream:
parking_data = yaml.load(stream)
parking_contours = []
parking_bounding_rects = []
parking_mask = []
parking_data_motion = []
if parking_data != None:
for park in parking_data:
points = np.array(park['points'])
rect = cv2.boundingRect(points)
points_shifted = points.copy()
points_shifted[:, 0] = points[:, 0] - rect[0] # shift contour to region of interest
points_shifted[:, 1] = points[:, 1] - rect[1]
parking_contours.append(points)
parking_bounding_rects.append(rect)
mask = cv2.drawContours(np.zeros((rect[3], rect[2]), dtype=np.uint8), [points_shifted], contourIdx=-1,
color = 255, thickness=-1, lineType=cv2.LINE_8)
mask = mask == 255
parking_mask.append(mask)
kernel_erode = cv2.getStructuringElement(cv2.MORPH_ELLIPSE,(3,3)) # morphological kernel
kernel_dilate = cv2.getStructuringElement(cv2.MORPH_RECT,(5,19))
if parking_data != None:
parking_status = [False]*len(parking_data)
parking_buffer = [None]*len(parking_data)
# bw = ()
def print_parkIDs(park, coor_points, frame_rev):
moments = cv2.moments(coor_points)
centroid = (int(moments['m10']/moments['m00'])-3, int(moments['m01']/moments['m00'])+3)
# putting numbers on marked regions
cv2.putText(frame_rev, str(park['id']), (centroid[0]+1, centroid[1]+1), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (255,255,255), 1, cv2.LINE_AA)
cv2.putText(frame_rev, str(park['id']), (centroid[0]-1, centroid[1]-1), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (255,255,255), 1, cv2.LINE_AA)
cv2.putText(frame_rev, str(park['id']), (centroid[0]+1, centroid[1]-1), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (255,255,255), 1, cv2.LINE_AA)
cv2.putText(frame_rev, str(park['id']), (centroid[0]-1, centroid[1]+1), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (255,255,255), 1, cv2.LINE_AA)
cv2.putText(frame_rev, str(park['id']), centroid, cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0,0,0), 1, cv2.LINE_AA)
while(cap.isOpened()):
video_cur_pos = cap.get(cv2.CAP_PROP_POS_MSEC) / 1000.0 # Current position of the video file in seconds
video_cur_frame = cap.get(cv2.CAP_PROP_POS_FRAMES) # Index of the frame to be decoded/captured next
ret, frame_initial = cap.read()
if ret == True:
frame = cv2.resize(frame_initial, None, fx=0.6, fy=0.6)
if ret == False:
print("Video ended")
break
# Background Subtraction
frame_blur = cv2.GaussianBlur(frame.copy(), (5,5), 3)
# frame_blur = frame_blur[150:1000, 100:1800]
frame_gray = cv2.cvtColor(frame_blur, cv2.COLOR_BGR2GRAY)
frame_out = frame.copy()
# Drawing the Overlay. Text overlay at the left corner of screen
if dict['text_overlay']:
str_on_frame = "%d/%d" % (video_cur_frame, video_info['num_of_frames'])
cv2.putText(frame_out, str_on_frame, (5, 30), cv2.FONT_HERSHEY_SIMPLEX,
0.8, (0, 255, 255), 2, cv2.LINE_AA)
cv2.putText(frame_out,global_str + str(round(change_pos, 2)) + 'sec', (5, 60), cv2.FONT_HERSHEY_SIMPLEX,
0.8, (255, 0, 0), 2, cv2.LINE_AA)
# motion detection for all objects
if dict['motion_detection']:
# frame_blur = frame_blur[380:420, 240:470]
# cv2.imshow('dss', frame_blur)
fgmask = fgbg.apply(frame_blur)
bw = np.uint8(fgmask==255)*255
bw = cv2.erode(bw, kernel_erode, iterations=1)
bw = cv2.dilate(bw, kernel_dilate, iterations=1)
# cv2.imshow('dss',bw)
# cv2.imwrite("frame%d.jpg" % co, bw)
(_, cnts, _) = cv2.findContours(bw.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
# loop over the contours
for c in cnts:
# print(cv2.contourArea(c))
# if the contour is too small, we ignore it
if cv2.contourArea(c) < dict['min_area_motion_contour']:
continue
(x, y, w, h) = cv2.boundingRect(c)
cv2.rectangle(frame_out, (x, y), (x + w, y + h), (255, 0, 0), 1)
# detecting cars and vacant spaces
if dict['parking_detection']:
for ind, park in enumerate(parking_data):
points = np.array(park['points'])
rect = parking_bounding_rects[ind]
roi_gray = frame_gray[rect[1]:(rect[1]+rect[3]), rect[0]:(rect[0]+rect[2])] # crop roi for faster calcluation
laplacian = cv2.Laplacian(roi_gray, cv2.CV_64F)
# cv2.imshow('oir', laplacian)
points[:, 0] = points[:, 0] - rect[0] # shift contour to roi
points[:, 1] = points[:, 1] - rect[1]
delta = np.mean(np.abs(laplacian * parking_mask[ind]))
# if(delta<2.5):
# print("ind, del", ind, delta)
status = delta < dict['park_laplacian_th']
# If detected a change in parking status, save the current time
if status != parking_status[ind] and parking_buffer[ind]==None:
parking_buffer[ind] = video_cur_pos
change_pos = video_cur_pos
# print("state ", ind,delta)
# applying classifier in case a change is detected in the status of area
# if dict['classifier_used']:
# classifier_result = run_classifier(roi_gray)
# if classifier_result:
# print(classifier_result)
# If status is still different than the one saved and counter is open
elif status != parking_status[ind] and parking_buffer[ind] != None:
if video_cur_pos - parking_buffer[ind] > dict['park_sec_to_wait']:
parking_status[ind] = status
parking_buffer[ind] = None
# If status is still same and counter is open
elif status == parking_status[ind] and parking_buffer[ind] != None:
parking_buffer[ind] = None
# changing the color on the basis on status change occured in the above section and putting numbers on areas
if dict['parking_overlay']:
for ind, park in enumerate(parking_data):
points = np.array(park['points'])
if parking_status[ind]:
color = (0, 255, 0)
rect = parking_bounding_rects[ind]
roi_gray_ov = frame_gray[rect[1]:(rect[1] + rect[3]),
rect[0]:(rect[0] + rect[2])] # crop roi for faster calcluation
res = run_classifier(roi_gray_ov, ind)
if res:
parking_data_motion.append(parking_data[ind])
# del parking_data[ind]
color = (0, 0, 255)
else:
color = (0, 0, 255)
cv2.drawContours(frame_out, [points], contourIdx=-1,
color=color, thickness=2, lineType=cv2.LINE_8)
if dict['show_ids']:
print_parkIDs(park, points, frame_out)
if parking_data_motion != []:
for index, park_coord in enumerate(parking_data_motion):
points = np.array(park_coord['points'])
color = (0, 0, 255)
recta = parking_bounding_rects[ind]
roi_gray1 = frame_gray[recta[1]:(recta[1] + recta[3]),
recta[0]:(recta[0] + recta[2])] # crop roi for faster calcluation
# laplacian = cv2.Laplacian(roi_gray, cv2.CV_64F)
# delta2 = np.mean(np.abs(laplacian * parking_mask[ind]))
# state = delta2<1
# classifier_result = run_classifier(roi_gray1, index)
# cv2.imshow('dsd', roi_gray1)
fgbg1 = cv2.createBackgroundSubtractorMOG2(history=300, varThreshold=16, detectShadows=True)
roi_gray1_blur = cv2.GaussianBlur(roi_gray1.copy(), (5, 5), 3)
# cv2.imshow('sd', roi_gray1_blur)
fgmask1 = fgbg1.apply(roi_gray1_blur)
bw1 = np.uint8(fgmask1 == 255) * 255
bw1 = cv2.erode(bw1, kernel_erode, iterations=1)
bw1 = cv2.dilate(bw1, kernel_dilate, iterations=1)
# cv2.imshow('sd', bw1)
# cv2.imwrite("frame%d.jpg" % co, bw)
(_, cnts1, _) = cv2.findContours(bw1.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
# loop over the contours
for c in cnts1:
print(cv2.contourArea(c))
# if the contour is too small, we ignore it
if cv2.contourArea(c) < 4:
continue
(x, y, w, h) = cv2.boundingRect(c)
classifier_result1 = run_classifier(roi_gray1, index)
if classifier_result1:
# print(classifier_result)
color = (0, 0, 255) # Red again if car found by classifier
else:
color = (0,255, 0)
classifier_result1 = run_classifier(roi_gray1, index)
if classifier_result1:
# print(classifier_result)
color = (0, 0, 255) # Red again if car found by classifier
else:
color = (0, 255, 0)
cv2.drawContours(frame_out, [points], contourIdx=-1,
color=color, thickness=2, lineType=cv2.LINE_8)
if dict['pedestrian_detection']:
# detect people in the image. Slows down the program, requires high GPU speed
(rects, weights) = hog.detectMultiScale(frame, winStride=(4, 4), padding=(8, 8), scale=1.05)
# draw the bounding boxes
for (x, y, w, h) in rects:
cv2.rectangle(frame_out, (x, y), (x + w, y + h), (255, 0, 0), 2)
# write the output frames
if dict['save_video']:
#if video_cur_frame % 35 == 0: # take every 30 frames
out.write(frame_out)
# Display video
cv2.imshow('frame', frame_out)
# cv2.imshow('background mask', bw)
k = cv2.waitKey(1)
if k == ord('q'):
break
elif k == ord('c'):
cv2.imwrite('frame%d.jpg' % video_cur_frame, frame_out)
elif k == ord('j'):
cap.set(cv2.CAP_PROP_POS_FRAMES, video_cur_frame+1000) # jump 1000 frames
elif k == ord('u'):
cap.set(cv2.CAP_PROP_POS_FRAMES, video_cur_frame + 500) # jump 500 frames
if cv2.waitKey(33) == 27:
break
cv2.waitKey(0)
cap.release()
if dict['save_video']: out.release()
cv2.destroyAllWindows()
change your these lines
`if dict['save_video']:
fourcc = cv2.VideoWriter_fourcc('X','V','I','D') # options: ('P','I','M','1'), ('D','I','V','X'), ('M','J','P','G'), ('X','V','I','D')
out = cv2.VideoWriter(fn_out, -1, 25.0,(video_info['width'], video_info['height']))`
to
`if dict['save_video']:
fourcc = cv2.VideoWriter_fourcc(*'XVID') # options: ('P','I','M','1'), ('D','I','V','X'), ('M','J','P','G'), ('X','V','I','D')
out = cv2.VideoWriter(fn_out, fourcc, 25.0,(video_info['width'], video_info['height']))`
and try again
Also put your functions/methods definitions to the top of the code.