def run(): # construct the argument parse and parse the arguments ap = argparse.ArgumentParser() ap.add_argument("-p", "--prototxt", required=False, help="path to Caffe 'deploy' prototxt file") ap.add_argument("-m", "--model", required=True, help="path to Caffe pre-trained model") ap.add_argument("-i", "--input", type=str, help="path to optional input video file") ap.add_argument("-o", "--output", type=str, help="path to optional output video file") # confidence default 0.4 ap.add_argument("-c", "--confidence", type=float, default=0.4, help="minimum probability to filter weak detections") ap.add_argument("-s", "--skip-frames", type=int, default=30, help="# of skip frames between detections") args = vars(ap.parse_args()) # initialize the list of class labels MobileNet SSD was trained to # detect CLASSES = [ "background", "aeroplane", "bicycle", "bird", "boat", "bottle", "bus", "car", "cat", "chair", "cow", "diningtable", "dog", "horse", "motorbike", "person", "pottedplant", "sheep", "sofa", "train", "tvmonitor" ] # load our serialized model from disk net = cv2.dnn.readNetFromCaffe(args["prototxt"], args["model"]) net.setPreferableBackend(cv2.dnn.DNN_BACKEND_CUDA) net.setPreferableTarget(cv2.dnn.DNN_TARGET_CUDA) # if a video path was not supplied, grab a reference to the ip camera if not args.get("input", False): print("[INFO] Starting the live stream..") vs = VideoStream(config.url).start() time.sleep(2.0) # otherwise, grab a reference to the video file else: print("[INFO] Starting the video..") #vs = cv2.VideoCapture('v4l2src device=/dev/video0 ! video/x-raw, format=YUY2, framerate=30/1, width=640, height=480 ! videoconvert ! appsink', cv2.CAP_GSTREAMER) vs = cv2.VideoCapture(0) # initialize the video writer (we'll instantiate later if need be) writer = None #gst_out2 = "appsrc ! video/x-raw ! videoconvert ! x264enc tune=zerolatency bitrate=500 speed-preset=superfast ! rtph264pay config-interval=1 ! udpsink host=127.0.0.1 port=10000" #writer2 =cv2.VideoWriter(gst_out2,cv2.CAP_GSTREAMER,0,float(20),(640,480),True) # initialize the frame dimensions (we'll set them as soon as we read # the first frame from the video) W = None H = None # instantiate our centroid tracker, then initialize a list to store # each of our dlib correlation trackers, followed by a dictionary to # map each unique object ID to a TrackableObject ct = CentroidTracker(maxDisappeared=50, maxDistance=50) trackers = [] trackableObjects = {} # initialize the total number of frames processed thus far, along # with the total number of objects that have moved either up or down totalFrames = 0 total = 0 x = [] empty = [] empty1 = [] #cp_frame = np.zeros((480,640,3), dtype=np.uint8) # start the frames per second throughput estimator fps = FPS().start() if config.Thread: vs = thread.ThreadingClass(config.url) # loop over frames from the video stream while True: # grab the next frame and handle if we are reading from either # VideoCapture or VideoStream _, frame = vs.read() start_time = time.time() #cp_frame = frame.copy() #frame = frame[1] if args.get("input", False) else frame # cv2.imshow("Real-Time Monitoring/Analysis W333dow", frame) # if we are viewing a video and we did not grab a frame then we # have reached the end of the video if args["input"] is not None and frame is None: break # resize the frame to have a maximum width of 500 pixels (the # less data we have, the faster we can process it), then convert # the frame from BGR to RGB for dlib frame = imutils.resize(frame, width=500) rgb = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB) # if the frame dimensions are empty, set them if W is None or H is None: (H, W) = frame.shape[:2] # if we are supposed to be writing a video to disk, initialize # the writer if args["output"] is not None and writer is None: fourcc = cv2.VideoWriter_fourcc(*"MJPG") writer = cv2.VideoWriter(args["output"], fourcc, 30, (W, H), True) # initialize the current status along with our list of bounding # box rectangles returned by either (1) our object detector or # (2) the correlation trackers status = "Waiting" rects = [] # check to see if we should run a more computationally expensive # object detection method to aid our tracker if totalFrames % args["skip_frames"] == 0: # set the status and initialize our new set of object trackers status = "Detecting" trackers = [] # convert the frame to a blob and pass the blob through the # network and obtain the detections blob = cv2.dnn.blobFromImage(frame, 0.00392, (W, H), 127.5) net.setInput(blob) detections = net.forward() # loop over the detections for i in np.arange(0, detections.shape[2]): # extract the confidence (i.e., probability) associated # with the prediction confidence = detections[0, 0, i, 2] # filter out weak detections by requiring a minimum # confidence if confidence > args["confidence"]: # extract the index of the class label from the # detections list idx = int(detections[0, 0, i, 1]) # if the class label is not a person, ignore it if CLASSES[idx] != "person": continue # compute the (x, y)-coordinates of the bounding box # for the object box = detections[0, 0, i, 3:7] * np.array([W, H, W, H]) (startX, startY, endX, endY) = box.astype("int") # construct a dlib rectangle object from the bounding # box coordinates and then start the dlib correlation # tracker tracker = dlib.correlation_tracker() rect = dlib.rectangle(startX, startY, endX, endY) tracker.start_track(rgb, rect) # add the tracker to our list of trackers so we can # utilize it during skip frames trackers.append(tracker) # otherwise, we should utilize our object *trackers* rather than # object *detectors* to obtain a higher frame processing throughput else: # loop over the trackers for tracker in trackers: # set the status of our system to be 'tracking' rather # than 'waiting' or 'detecting' status = "Tracking" # update the tracker and grab the updated position tracker.update(rgb) pos = tracker.get_position() # unpack the position object startX = int(pos.left()) startY = int(pos.top()) endX = int(pos.right()) endY = int(pos.bottom()) # add the bounding box coordinates to the rectangles list rects.append((startX, startY, endX, endY)) # draw a horizontal line in the center of the frame -- once an # object crosses this line we will determine whether they were # moving 'up' or 'down' # cv2.line(frame, (0, H // 2), (W, H // 2), (0, 0, 0), 3) # cv2.putText(frame, "-Prediction border - Entrance-", (10, H - ((i * 20) + 200)), # cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 0, 0), 1) # use the centroid tracker to associate the (1) old object # centroids with (2) the newly computed object centroids objects = ct.update(rects) total = len(objects) # loop over the tracked objects for (objectID, centroid) in objects.items(): # check to see if a trackable object exists for the current # object ID to = trackableObjects.get(objectID, None) # if there is no existing trackable object, create one if to is None: to = TrackableObject(objectID, centroid) # define timestamp frames and logs trackableObjects[objectID] = to # draw both the ID of the object and the centroid of the # object on the output frame text = "ID {}".format(objectID) cv2.putText(frame, text, (centroid[0] - 10, centroid[1] - 10), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (255, 255, 255), 2) cv2.circle(frame, (centroid[0], centroid[1]), 4, (255, 255, 255), -1) # construct a tuple of information we will be displaying on the info = [ ("Exit", total), ("Status", status), ] # Display the output for (i, (k, v)) in enumerate(info): text = "{}: {}".format(k, v) cv2.putText(frame, text, (10, H - ((i * 20) + 20)), cv2.FONT_HERSHEY_SIMPLEX, 0.6, (0, 0, 0), 2) # show the output frame cv2.imshow("Real-Time Monitoring/Analysis Window", frame) #if total >= 2: #writer2.write(cp_frame) key = cv2.waitKey(1) & 0xFF # if the `q` key was pressed, break from the loop if key == ord("q"): break # increment the total number of frames processed thus far and # then update the FPS counter totalFrames += 1 fps.update() # stop the timer and display FPS information fps.stop() print("[INFO] elapsed time: {:.2f}".format(fps.elapsed())) print("[INFO] approx. FPS: {:.2f}".format(fps.fps())) # # if we are not using a video file, stop the camera video stream # if not args.get("input", False): # vs.stop() # # # otherwise, release the video file pointer # else: # vs.release() # close any open windows cv2.destroyAllWindows()
def run(): # construct the argument parse and parse the arguments ap = argparse.ArgumentParser() ap.add_argument("-p", "--prototxt", required=False, help="path to Caffe 'deploy' prototxt file") ap.add_argument("-m", "--model", required=True, help="path to Caffe pre-trained model") ap.add_argument("-i", "--input", type=str, help="path to optional input video file") ap.add_argument("-o", "--output", type=str, help="path to optional output video file") # confidence default 0.4 ap.add_argument("-c", "--confidence", type=float, default=0.4, help="minimum probability to filter weak detections") ap.add_argument("-s", "--skip-frames", type=int, default=30, help="# of skip frames between detections") args = vars(ap.parse_args()) # initialize the list of class labels MobileNet SSD was trained to # detect CLASSES = ["background", "aeroplane", "bicycle", "bird", "boat", "bottle", "bus", "car", "cat", "chair", "cow", "diningtable", "dog", "horse", "motorbike", "person", "pottedplant", "sheep", "sofa", "train", "tvmonitor"] # load our serialized model from disk net = cv2.dnn.readNetFromCaffe(args["prototxt"], args["model"]) # if a video path was not supplied, grab a reference to the ip camera if not args.get("input", False): print("[INFO] Starting the live stream..") vs = VideoStream(config.url).start() time.sleep(2.0) # otherwise, grab a reference to the video file else: print("[INFO] Starting the video..") vs = cv2.VideoCapture(args["input"]) # initialize the video writer (we'll instantiate later if need be) writer = None # initialize the frame dimensions (we'll set them as soon as we read # the first frame from the video) W = None H = None # instantiate our centroid tracker, then initialize a list to store # each of our dlib correlation trackers, followed by a dictionary to # map each unique object ID to a TrackableObject ct = CentroidTracker(maxDisappeared=40, maxDistance=50) trackers = [] trackableObjects = {} # initialize the total number of frames processed thus far, along # with the total number of objects that have moved either up or down totalFrames = 0 totalDown = 0 totalUp = 0 x = [] empty=[] empty1=[] # start the frames per second throughput estimator fps = FPS().start() if config.Thread: vs = thread.ThreadingClass(config.url) # loop over frames from the video stream while True: # grab the next frame and handle if we are reading from either # VideoCapture or VideoStream frame = vs.read() frame = frame[1] if args.get("input", False) else frame # if we are viewing a video and we did not grab a frame then we # have reached the end of the video if args["input"] is not None and frame is None: break # resize the frame to have a maximum width of 500 pixels (the # less data we have, the faster we can process it), then convert # the frame from BGR to RGB for dlib frame = imutils.resize(frame, width = 500) rgb = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB) # if the frame dimensions are empty, set them if W is None or H is None: (H, W) = frame.shape[:2] # if we are supposed to be writing a video to disk, initialize # the writer if args["output"] is not None and writer is None: fourcc = cv2.VideoWriter_fourcc(*"MJPG") writer = cv2.VideoWriter(args["output"], fourcc, 30, (W, H), True) # initialize the current status along with our list of bounding # box rectangles returned by either (1) our object detector or # (2) the correlation trackers status = "Waiting" rects = [] # check to see if we should run a more computationally expensive # object detection method to aid our tracker if totalFrames % args["skip_frames"] == 0: # set the status and initialize our new set of object trackers status = "Detecting" trackers = [] # convert the frame to a blob and pass the blob through the # network and obtain the detections blob = cv2.dnn.blobFromImage(frame, 0.007843, (W, H), 127.5) net.setInput(blob) detections = net.forward() # loop over the detections for i in np.arange(0, detections.shape[2]): # extract the confidence (i.e., probability) associated # with the prediction confidence = detections[0, 0, i, 2] # filter out weak detections by requiring a minimum # confidence if confidence > args["confidence"]: # extract the index of the class label from the # detections list idx = int(detections[0, 0, i, 1]) # if the class label is not a person, ignore it if CLASSES[idx] != "person": continue # compute the (x, y)-coordinates of the bounding box # for the object box = detections[0, 0, i, 3:7] * np.array([W, H, W, H]) (startX, startY, endX, endY) = box.astype("int") # construct a dlib rectangle object from the bounding # box coordinates and then start the dlib correlation # tracker tracker = dlib.correlation_tracker() rect = dlib.rectangle(startX, startY, endX, endY) tracker.start_track(rgb, rect) # add the tracker to our list of trackers so we can # utilize it during skip frames trackers.append(tracker) # otherwise, we should utilize our object *trackers* rather than # object *detectors* to obtain a higher frame processing throughput else: # loop over the trackers for tracker in trackers: # set the status of our system to be 'tracking' rather # than 'waiting' or 'detecting' status = "Tracking" # update the tracker and grab the updated position tracker.update(rgb) pos = tracker.get_position() # unpack the position object startX = int(pos.left()) startY = int(pos.top()) endX = int(pos.right()) endY = int(pos.bottom()) # add the bounding box coordinates to the rectangles list rects.append((startX, startY, endX, endY)) # draw a horizontal line in the center of the frame -- once an # object crosses this line we will determine whether they were # moving 'up' or 'down' cv2.line(frame, (0, H // 2), (W, H // 2), (0, 0, 0), 3) cv2.putText(frame, "-Prediction border - Entrance-", (10, H - ((i * 20) + 200)), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 0, 0), 1) # use the centroid tracker to associate the (1) old object # centroids with (2) the newly computed object centroids objects = ct.update(rects) # loop over the tracked objects for (objectID, centroid) in objects.items(): # check to see if a trackable object exists for the current # object ID to = trackableObjects.get(objectID, None) # if there is no existing trackable object, create one if to is None: to = TrackableObject(objectID, centroid) # otherwise, there is a trackable object so we can utilize it # to determine direction else: # the difference between the y-coordinate of the *current* # centroid and the mean of *previous* centroids will tell # us in which direction the object is moving (negative for # 'up' and positive for 'down') y = [c[1] for c in to.centroids] direction = centroid[1] - np.mean(y) to.centroids.append(centroid) # check to see if the object has been counted or not if not to.counted: # if the direction is negative (indicating the object # is moving up) AND the centroid is above the center # line, count the object if direction < 0 and centroid[1] < H // 2: totalUp += 1 empty.append(totalUp) to.counted = True # if the direction is positive (indicating the object # is moving down) AND the centroid is below the # center line, count the object elif direction > 0 and centroid[1] > H // 2: totalDown += 1 empty1.append(totalDown) #print(empty1[-1]) x = [] # compute the sum of total people inside x.append(len(empty1)-len(empty)) #print("Total people inside:", x) # if the people limit exceeds over threshold, send an email alert if sum(x) >= config.Threshold: cv2.putText(frame, "-ALERT: People limit exceeded-", (10, frame.shape[0] - 80), cv2.FONT_HERSHEY_COMPLEX, 0.5, (0, 0, 255), 2) if config.ALERT: print("[INFO] Sending email alert..") Mailer().send(config.MAIL) print("[INFO] Alert sent") to.counted = True # store the trackable object in our dictionary trackableObjects[objectID] = to # draw both the ID of the object and the centroid of the # object on the output frame text = "ID {}".format(objectID) cv2.putText(frame, text, (centroid[0] - 10, centroid[1] - 10), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (255, 255, 255), 2) cv2.circle(frame, (centroid[0], centroid[1]), 4, (255, 255, 255), -1) # construct a tuple of information we will be displaying on the info = [ ("Exit", totalUp), ("Enter", totalDown), ("Status", status), ] info2 = [ ("Total people inside", x), ] # Display the output for (i, (k, v)) in enumerate(info): text = "{}: {}".format(k, v) cv2.putText(frame, text, (10, H - ((i * 20) + 20)), cv2.FONT_HERSHEY_SIMPLEX, 0.6, (0, 0, 0), 2) for (i, (k, v)) in enumerate(info2): text = "{}: {}".format(k, v) cv2.putText(frame, text, (265, H - ((i * 20) + 60)), cv2.FONT_HERSHEY_SIMPLEX, 0.6, (255, 255, 255), 2) # Initiate a simple log to save data at end of the day if config.Log: datetimee = [datetime.datetime.now()] d = [datetimee, empty1, empty, x] export_data = zip_longest(*d, fillvalue = '') with open('Log.csv', 'w', newline='') as myfile: wr = csv.writer(myfile, quoting=csv.QUOTE_ALL) wr.writerow(("End Time", "In", "Out", "Total Inside")) wr.writerows(export_data) # show the output frame cv2.imshow("Real-Time Monitoring/Analysis Window", frame) key = cv2.waitKey(1) & 0xFF # if the `q` key was pressed, break from the loop if key == ord("q"): break # increment the total number of frames processed thus far and # then update the FPS counter totalFrames += 1 fps.update() if config.Timer: # Automatic timer to stop the live stream. Set to 8 hours (28800s). t1 = time.time() num_seconds=(t1-t0) if num_seconds > 28800: break # stop the timer and display FPS information fps.stop() print("[INFO] elapsed time: {:.2f}".format(fps.elapsed())) print("[INFO] approx. FPS: {:.2f}".format(fps.fps())) # # if we are not using a video file, stop the camera video stream # if not args.get("input", False): # vs.stop() # # # otherwise, release the video file pointer # else: # vs.release() # issue 15 if config.Thread: vs.release() # close any open windows cv2.destroyAllWindows()
def run(): ap = argparse.ArgumentParser() ap.add_argument("-p", "--prototxt", required=False, help="path to Caffe 'deploy' prototxt file") ap.add_argument("-m", "--model", required=True, help="path to Caffe pre-trained model") ap.add_argument("-i", "--input", type=str, help="path to optional input video file") ap.add_argument("-o", "--output", type=str, help="path to optional output video file") # confidence default 0.4 ap.add_argument("-c", "--confidence", type=float, default=0.4, help="minimum probability to filter weak detections") ap.add_argument("-s", "--skip-frames", type=int, default=30, help="# of skip frames between detections") args = vars(ap.parse_args()) CLASSES = ["background", "aeroplane", "bicycle", "bird", "boat", "bottle", "bus", "car", "cat", "chair", "cow", "diningtable", "dog", "horse", "motorbike", "person", "pottedplant", "sheep", "sofa", "train", "tvmonitor"] #Uolo v3 MobilenetSSD net = cv2.dnn.readNetFromCaffe(args["prototxt"], args["model"]) if not args.get("input", False): print("[INFO] Starting the live stream..") vs = VideoStream(config.url).start() time.sleep(2.0) else: print("[INFO] Starting the video..") vs = cv2.VideoCapture(args["input"]) writer = None W = None H = None ct = CentroidTracker(maxDisappeared=40, maxDistance=50) trackers = [] trackableObjects = {} totalFrames = 0 totalDown = 0 totalUp = 0 x = [] empty=[] empty1=[] fps = FPS().start() if config.Thread: vs = thread.ThreadingClass(config.url) while True: frame = vs.read() frame = frame[1] if args.get("input", False) else frame if args["input"] is not None and frame is None: break frame = imutils.resize(frame, width = 500) rgb = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB) if W is None or H is None: (H, W) = frame.shape[:2] # if we are supposed to be writing a video to disk, initialize # the writer if args["output"] is not None and writer is None: fourcc = cv2.VideoWriter_fourcc(*"MJPG") writer = cv2.VideoWriter(args["output"], fourcc, 30, (W, H), True) status = "Waiting" rects = [] if totalFrames % args["skip_frames"] == 0: status = "Detecting" trackers = [] blob = cv2.dnn.blobFromImage(frame, 0.007843, (W, H), 127.5) net.setInput(blob) detections = net.forward() # loop over the detections for i in np.arange(0, detections.shape[2]): confidence = detections[0, 0, i, 2] if confidence > args["confidence"]: idx = int(detections[0, 0, i, 1]) if CLASSES[idx] != "person": continue box = detections[0, 0, i, 3:7] * np.array([W, H, W, H]) (startX, startY, endX, endY) = box.astype("int") # construct a dlib rectangle object from the bounding tracker = dlib.correlation_tracker() rect = dlib.rectangle(startX, startY, endX, endY) tracker.start_track(rgb, rect) trackers.append(tracker) else: for tracker in trackers: status = "Tracking" tracker.update(rgb) pos = tracker.get_position() # unpack the position object startX = int(pos.left()) startY = int(pos.top()) endX = int(pos.right()) endY = int(pos.bottom()) rects.append((startX, startY, endX, endY)) cv2.line(frame, (0, H // 2), (W, H // 2), (0, 0, 0), 3) cv2.putText(frame, "-Prediction border - Entrance-", (10, H - ((i * 20) + 200)), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 0, 0), 1) cv2.putText(frame, datetime.datetime.now().strftime("%A %d %B %Y %I:%M:%S%p"), (10, frame.shape[0] - 10), cv2.FONT_HERSHEY_SIMPLEX, 0.35, (0, 0, 255), 1) objects = ct.update(rects) # loop over the tracked objects for (objectID, centroid) in objects.items(): to = trackableObjects.get(objectID, None) if to is None: to = TrackableObject(objectID, centroid) else: y = [c[1] for c in to.centroids] direction = centroid[1] - np.mean(y) to.centroids.append(centroid) if not to.counted: if direction < 0 and centroid[1] < H // 2: totalUp += 1 empty.append(totalUp) to.counted = True elif direction > 0 and centroid[1] > H // 2: totalDown += 1 empty1.append(totalDown) #print(empty1[-1]) x = [] x.append(len(empty1)-len(empty)) #print("Total people inside:", x) if sum(x) >= config.Threshold: cv2.putText(frame, "-ALERT: People limit exceeded-", (10, frame.shape[0] - 80), cv2.FONT_HERSHEY_COMPLEX, 0.5, (0, 0, 255), 2) if config.ALERT: print("[INFO] Sending email alert..") Mailer().send(config.MAIL) print("[INFO] Alert sent") to.counted = True trackableObjects[objectID] = to text = "ID {}".format(objectID) cv2.putText(frame, text, (centroid[0] - 10, centroid[1] - 10), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (255, 255, 255), 2) cv2.circle(frame, (centroid[0], centroid[1]), 4, (255, 255, 255), -1) info = [ ("Exit", totalUp), ("Enter", totalDown), ("Status", status), ] info2 = [ ("Total people inside", x), ] for (i, (k, v)) in enumerate(info): text = "{}: {}".format(k, v) cv2.putText(frame, text, (10, H - ((i * 20) + 20)), cv2.FONT_HERSHEY_SIMPLEX, 0.6, (0, 0, 0), 2) for (i, (k, v)) in enumerate(info2): text = "{}: {}".format(k, v) cv2.putText(frame, text, (265, H - ((i * 20) + 60)), cv2.FONT_HERSHEY_SIMPLEX, 0.6, (255, 255, 255), 2) if config.Log: datetimee = [datetime.datetime.now()] d = [datetimee, empty1, empty, x] export_data = zip_longest(*d, fillvalue = '') with open('Log.csv', 'w', newline='') as myfile: wr = csv.writer(myfile, quoting=csv.QUOTE_ALL) wr.writerow(("End Time", "In", "Out", "Total Inside")) wr.writerows(export_data) cv2.imshow("Real-Time Monitoring/Analysis Window", frame) key = cv2.waitKey(1) & 0xFF if key == ord("q"): break totalFrames += 1 fps.update() if config.Timer: t1 = time.time() num_seconds=(t1-t0) if num_seconds > 28800: break fps.stop() print("[INFO] elapsed time: {:.2f}".format(fps.elapsed())) print("[INFO] approx. FPS: {:.2f}".format(fps.fps())) # if not args.get("input", False): # vs.stop() # # # otherwise, release the video file pointer # else: # vs.release() cv2.destroyAllWindows()
# set CUDA as the preferable backend and target print("") print("[INFO] Looking for GPU") net.setPreferableBackend(cv2.dnn.DNN_BACKEND_CUDA) net.setPreferableTarget(cv2.dnn.DNN_TARGET_CUDA) # determine only the *output* layer names that we need from YOLO ln = net.getLayerNames() ln = [ln[i[0] - 1] for i in net.getUnconnectedOutLayers()] # if a video path was not supplied, grab a reference to the camera if not args.get("input", False): print("[INFO] Starting the live stream..") vs = cv2.VideoCapture(config.url) if config.Thread: cap = thread.ThreadingClass(config.url) time.sleep(2.0) # otherwise, grab a reference to the video file else: print("[INFO] Starting the video..") vs = cv2.VideoCapture(args["input"]) if config.Thread: cap = thread.ThreadingClass(args["input"]) writer = None # start the FPS counter fps = FPS().start() # loop over the frames from the video stream while True:
def run(): # construir o argumento ap = argparse.ArgumentParser() ap.add_argument("-p", "--prototxt", required=False, help="path to Caffe 'deploy' prototxt file") ap.add_argument("-m", "--model", required=True, help="path to Caffe pre-trained model") ap.add_argument("-i", "--input", type=str, help="path to optional input video file") ap.add_argument("-o", "--output", type=str, help="path to optional output video file") # confidence default 0.4 ap.add_argument("-c", "--confidence", type=float, default=0.4, help="minimum probability to filter weak detections") ap.add_argument("-s", "--skip-frames", type=int, default=30, help="# of skip frames between detections") args = vars(ap.parse_args()) # inicializar a lista de rótulos de classe MobileNet SSD foi treinado para # detect CLASSES = [ "background", "aeroplane", "bicycle", "bird", "boat", "bottle", "bus", "car", "cat", "chair", "cow", "diningtable", "dog", "horse", "motorbike", "person", "pottedplant", "sheep", "sofa", "train", "tvmonitor" ] #carregar nosso modelo serializado do disco net = cv2.dnn.readNetFromCaffe(args["prototxt"], args["model"]) # se um caminho de vídeo não foi fornecido, pegue uma referência para a câmera ip if not args.get("input", False): print("[INFO] Starting the live stream..") vs = VideoStream(config.url).start() time.sleep(2.0) # caso contrário, pegue uma referência ao arquivo de vídeo else: print("[INFO] Starting the video..") vs = cv2.VideoCapture(args["input"]) # inicializar o gravador de vídeo (vamos instanciar mais tarde, se necessário) writer = None # inicializar as dimensões do quadro (vamos defini-los assim que lermos # o primeiro quadro do vídeo) W = None H = None # instanciar nosso rastreador de centróide e inicializar uma lista para armazenar # cada um de nossos rastreadores de correlação dlib, seguido por um dicionário para # mapeia cada ID de objeto exclusivo para um TrackableObject ct = CentroidTracker(maxDisappeared=40, maxDistance=50) trackers = [] trackableObjects = {} # credenciais do Firebase firebaseConfig = { "apiKey": "AIzaSyCCE4yveEuH_09vThP5U1J0Oi3d1-r2muY", "authDomain": "teste-90925.firebaseapp.com", "databaseURL": "https://teste-90925.firebaseio.com", "projectId": "teste-90925", "storageBucket": "teste-90925.appspot.com", "messagingSenderId": "267430548654", "appId": "1:267430548654:web:475cb40c90b836b32fc93f" } #inicializar o firebase firebase = pyrebase.initialize_app(firebaseConfig) # inicializa o número total de frames processados até agora, junto # com o número total de objetos que se moveram para cima ou para baixo totalFrames = 0 totalDown = 0 totalUp = 0 x = [] empty = [] empty1 = [] dados = firebase.database( ) # variavel para receber as informações do firebase # iniciar o estimador de taxa de frames por segundo fps = FPS().start() if config.Thread: vs = thread.ThreadingClass(config.url) # faz um loop sobre os frames do stream de vídeo while True: # pega o próximo quadro e controla se estivermos lendo de qualquer # VideoCapture ou VideoStream frame = vs.read() frame = frame[1] if args.get("input", False) else frame # se estamos assistindo a um vídeo e não capturamos um quadro, então # chegou ao final do vídeo if args["input"] is not None and frame is None: break # redimensiona o quadro para ter uma largura máxima de 500 pixels (o # menos dados temos, mais rápido podemos processá-los) e, em seguida, converter # o quadro de BGR para RGB para dlib frame = imutils.resize(frame, width=500) rgb = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB) # se as dimensões do quadro estiverem vazias, defina-as if W is None or H is None: (H, W) = frame.shape[:2] # se deveríamos estar gravando um vídeo no disco, inicialize # the writer if args["output"] is not None and writer is None: fourcc = cv2.VideoWriter_fourcc(*"MJPG") writer = cv2.VideoWriter(args["output"], fourcc, 30, (W, H), True) # inicializar o status atual junto com nossa lista de # retângulos de caixa retornados por (1) nosso detector de objetos ou # (2) os rastreadores de correlação status = "Waiting" rects = [] # verifique se devemos executar um computador # método de detecção de objeto para ajudar nosso rastreador if totalFrames % args["skip_frames"] == 0: # set the status and initialize our new set of object trackers status = "Detectando" trackers = [] # converter o quadro em um blob # rede e obter as detecções blob = cv2.dnn.blobFromImage(frame, 0.007843, (W, H), 127.5) net.setInput(blob) detections = net.forward() # loop nas detecções for i in np.arange(0, detections.shape[2]): # extrair a confiança (ou seja, probabilidade) associada # com a previsão confidence = detections[0, 0, i, 2] # filter out weak detections by requiring a minimum # confidence if confidence > args["confidence"]: # filtrar detecções fracas exigindo um mínimo # confiança idx = int(detections[0, 0, i, 1]) # se o rótulo da classe não for uma pessoa, ignore-o if CLASSES[idx] != "person": continue # calcule as coordenadas (x, y) da caixa delimitadora # para o objeto box = detections[0, 0, i, 3:7] * np.array([W, H, W, H]) (startX, startY, endX, endY) = box.astype("int") # constrói um objeto retângulo dlib a partir do limite # box coordena e então inicia a correlação dlib # rastreador tracker = dlib.correlation_tracker() rect = dlib.rectangle(startX, startY, endX, endY) tracker.start_track(rgb, rect) # adicione o rastreador à nossa lista de rastreadores para que possamos # utilizá-lo durante pular quadros trackers.append(tracker) # caso contrário, devemos utilizar nossos objetos * rastreadores * em vez de # objeto * detectores * para obter uma maior taxa de processamento de quadros else: # loop sobre os rastreadores for tracker in trackers: # definir o status do nosso sistema para 'rastreamento' em vez # do que 'esperando' ou 'detectando' status = "Rastreamento" # atualize o rastreador e pegue a posição atualizada tracker.update(rgb) pos = tracker.get_position() # desempacote o objeto de posição startX = int(pos.left()) startY = int(pos.top()) endX = int(pos.right()) endY = int(pos.bottom()) # adicione as coordenadas da caixa delimitadora à lista de retângulos rects.append((startX, startY, endX, endY)) # desenhe uma linha horizontal no centro do quadro - uma vez que # objeto cruza esta linha, determinaremos se eles foram # movendo 'para cima' ou 'para baixo' cv2.line(frame, (0, H // 2), (W, H // 2), (0, 0, 0), 3) cv2.putText(frame, "-Linha da Previsão - Entrada-", (10, H - ((i * 20) + 200)), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 0, 0), 1) # use o rastreador de centróide para associar o (1) objeto antigo # centróides com (2) os centróides de objeto recém-computados objects = ct.update(rects) # loop sobre os objetos rastreados for (objectID, centroid) in objects.items(): # verifique se existe um objeto rastreável para o atual # ID do objeto to = trackableObjects.get(objectID, None) # se não houver nenhum objeto rastreável existente, crie um if to is None: to = TrackableObject(objectID, centroid) # caso contrário, há um objeto rastreável para que possamos utilizá-lo # para determinar a direção else: # a diferença entre a coordenada y da * atual * # centróide e a média dos * anteriores * centróides dirão # em que direção o objeto está se movendo (negativo para 'para cima' e positivo para 'para baixo') y = [c[1] for c in to.centroids] direction = centroid[1] - np.mean(y) to.centroids.append(centroid) # verifique se o objeto foi contado ou não if not to.counted: # se a direção for negativa (indicando o objeto # está se movendo para cima) E o centróide está acima do centro # linha, conte o objeto if direction < 0 and centroid[1] < H // 2: totalUp += 1 empty.append(totalUp) to.counted = True # se a direção for positiva (indicando o objeto # está se movendo para baixo) E o centróide está abaixo do # linha central, conte o objeto elif direction > 0 and centroid[1] > H // 2: totalDown += 1 empty1.append(totalDown) #print(empty1[-1]) x = [] # calcula a soma do total de pessoas dentro x.append(len(empty1) - len(empty)) #print("Total people inside:", x) # Otimize o número abaixo: 10, 50, 100, etc., indique o máx. pessoas dentro do limite # se o limite exceder, envie um alerta por email people_limit = 10 dados.child().update({"entrada": totalDown}) dados.child().update({"saida": totalUp}) if sum(x) == people_limit: if config.ALERT: print("[INFO] Sending email alert..") Mailer().send(config.MAIL) print("[INFO] Alert sent") to.counted = True # armazene o objeto rastreável em nosso dicionário trackableObjects[objectID] = to # desenha o ID do objeto e o centroide do # objeto no quadro de saída text = "ID {}".format(objectID) cv2.putText(frame, text, (centroid[0] - 10, centroid[1] - 10), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (255, 255, 255), 2) cv2.circle(frame, (centroid[0], centroid[1]), 4, (255, 255, 255), -1) #constrói as informações que serão exibidas no display info = [ ("Exit", totalUp), ("Enter", totalDown), ("Status", status), ] info2 = [ ("Total no momento", x), ] # Exibir Saída for (i, (k, v)) in enumerate(info): text = "{}: {}".format(k, v) cv2.putText(frame, text, (10, H - ((i * 20) + 20)), cv2.FONT_HERSHEY_SIMPLEX, 0.6, (0, 0, 0), 2) for (i, (k, v)) in enumerate(info2): text = "{}: {}".format(k, v) cv2.putText(frame, text, (265, H - ((i * 20) + 60)), cv2.FONT_HERSHEY_SIMPLEX, 0.6, (255, 255, 255), 2) # Inicie um registro simples para salvar os dados no final do dia if config.Log: datetimee = [datetime.datetime.now()] d = [datetimee, empty1, empty, x] export_data = zip_longest(*d, fillvalue='') with open('Log.csv', 'w', newline='') as myfile: wr = csv.writer(myfile, quoting=csv.QUOTE_ALL) wr.writerow(("End Time", "In", "Out", "Total Inside")) wr.writerows(export_data) # show the output frame cv2.imshow("Real-Time Monitoring/Analysis Window", frame) key = cv2.waitKey(1) & 0xFF # se a tecla `q` foi pressionada, interrompa o loop if key == ord("q"): break # incrementa o número total de frames processados até agora e # então atualize o contador FPS totalFrames += 1 fps.update() if config.Timer: # Temporizador automático para parar a transmissão ao vivo. Defina para 8 horas (28800s). t1 = time.time() num_seconds = (t1 - t0) if num_seconds > 28800: break # parar o cronômetro e exibir informações FPS fps.stop() print("[INFO] elapsed time: {:.2f}".format(fps.elapsed())) print("[INFO] approx. FPS: {:.2f}".format(fps.fps())) # # se não estivermos usando um arquivo de vídeo, pare o stream de vídeo da câmera # se não for args.get ("input", False): # vs.stop () # # # caso contrário, solte o ponteiro do arquivo de vídeo # outro: # vs.release () # feche todas as janelas abertas cv2.destroyAllWindows()
def gen_frames(): CLASSES = [ "background", "aeroplane", "bicycle", "bird", "boat", "bottle", "bus", "car", "cat", "chair", "cow", "diningtable", "dog", "horse", "motorbike", "person", "pottedplant", "sheep", "sofa", "train", "tvmonitor", ] net = cv2.dnn.readNetFromCaffe(config.PROTOTXT, config.MODEL) print("[INFO] Starting the live stream..") vs = VideoStream(config.url).start() # vs = cv2.VideoCapture(config.url) time.sleep(2.0) writer = None W = None H = None ct = CentroidTracker(maxDisappeared=40, maxDistance=50) trackers = [] trackableObjects = {} totalFrames = 0 totalDown = 0 totalUp = 0 x = [] empty = [] empty1 = [] fps = FPS().start() if config.Thread: vs = thread.ThreadingClass(config.url) while True: frame = vs.read() if frame is None: break frame = imutils.resize(frame, width=500) # frame = cv2.resize(frame, (500, 500)) rgb = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB) if W is None or H is None: (H, W) = frame.shape[:2] status = "Waiting" rects = [] if totalFrames % config.Skip_frames == 0: status = "Detecting" trackers = [] blob = cv2.dnn.blobFromImage(frame, 0.007843, (W, H), 127.5) net.setInput(blob) detections = net.forward() for i in np.arange(0, detections.shape[2]): confidence = detections[0, 0, i, 2] if confidence > config.Confidence: idx = int(detections[0, 0, i, 1]) if CLASSES[idx] != "person": continue box = detections[0, 0, i, 3:7] * np.array([W, H, W, H]) (startX, startY, endX, endY) = box.astype("int") tracker = dlib.correlation_tracker() rect = dlib.rectangle(startX, startY, endX, endY) tracker.start_track(rgb, rect) trackers.append(tracker) else: for tracker in trackers: status = "Tracking" tracker.update(rgb) pos = tracker.get_position() startX = int(pos.left()) startY = int(pos.top()) endX = int(pos.right()) endY = int(pos.bottom()) rects.append((startX, startY, endX, endY)) cv2.line(frame, (0, H // 2), (W, H // 2), (0, 0, 0), 3) cv2.putText( frame, "-Prediction border - Entrance-", (10, H - ((i * 20) + 200)), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 0, 0), 1, ) objects = ct.update(rects) for (objectID, centroid) in objects.items(): to = trackableObjects.get(objectID, None) if to is None: to = TrackableObject(objectID, centroid) else: y = [c[1] for c in to.centroids] direction = centroid[1] - np.mean(y) to.centroids.append(centroid) if not to.counted: if direction < 0 and centroid[1] < H // 2: totalUp += 1 empty.append(totalUp) to.counted = True elif direction > 0 and centroid[1] > H // 2: totalDown += 1 empty1.append(totalDown) x = [] x.append(len(empty1) - len(empty)) if sum(x) >= config.Threshold: cv2.putText( frame, "-ALERT: People limit exceeded-", (10, frame.shape[0] - 80), cv2.FONT_HERSHEY_COMPLEX, 0.5, (0, 0, 255), 2, ) if config.ALERT: print("[INFO] Sending email alert..") Mailer().send(config.MAIL) print("[INFO] Alert sent") to.counted = True trackableObjects[objectID] = to text = "ID {}".format(objectID) cv2.putText( frame, text, (centroid[0] - 10, centroid[1] - 10), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (255, 255, 255), 2, ) cv2.circle(frame, (centroid[0], centroid[1]), 4, (255, 255, 255), -1) info = [ ("Exit", totalUp), ("Enter", totalDown), ("Status", status), ] info2 = [ ("Total people inside", x), ] for (i, (k, v)) in enumerate(info): text = "{}: {}".format(k, v) cv2.putText( frame, text, (10, H - ((i * 20) + 20)), cv2.FONT_HERSHEY_SIMPLEX, 0.6, (0, 0, 0), 2, ) for (i, (k, v)) in enumerate(info2): text = "{}: {}".format(k, v) cv2.putText( frame, text, (265, H - ((i * 20) + 60)), cv2.FONT_HERSHEY_SIMPLEX, 0.6, (255, 255, 255), 2, ) if config.Log: datetimee = [datetime.datetime.now()] d = [datetimee, empty1, empty, x] export_data = zip_longest(*d, fillvalue="") with open("Log.csv", "w", newline="") as myfile: wr = csv.writer(myfile, quoting=csv.QUOTE_ALL) wr.writerow(("End Time", "In", "Out", "Total Inside")) wr.writerows(export_data) ret, buffer = cv2.imencode(".jpg", frame) frame = buffer.tobytes() yield (b"--frame\r\n" b"Content-Type: image/jpeg\r\n\r\n" + frame + b"\r\n" ) # concat frame one by one and show result