Smart-Home am Beispiel der Präsenzerkennung im Raum Projektarbeit Lennart Heimbs, Johannes Krug, Sebastian Dohle und Kevin Holzschuh bei Prof. Oliver Hofmann SS2019
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

person_detection.py 8.5KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232
  1. #!/usr/bin/env python
  2. import argparse
  3. #from datetime import datetime, time
  4. import time
  5. from statistics import median
  6. import imutils
  7. from imutils.video import VideoStream
  8. #from imutils.video import FPS
  9. import cv2
  10. import numpy as np
  11. frame_timer = None
  12. contour_timer = None
  13. detection_timer = None
  14. frame_time = []
  15. contour_time = []
  16. detection_time = []
  17. VISUAL_DEBUG = True
  18. def getArgs():
  19. """ Arguments """
  20. ap = argparse.ArgumentParser()
  21. ap.add_argument("-v", "--video", help="path to the video file")
  22. ap.add_argument("-a", "--min-area", type=int, default=500, help="minimum area size")
  23. ap.add_argument("-t", "--tracker", type=str, default="csrt", help="OpenCV object tracker type")
  24. return vars(ap.parse_args())
  25. def main():
  26. args = getArgs()
  27. timer = Timer()
  28. # if the video argument is None, then the code will read from webcam (work in progress)
  29. if args.get("video", None) is None:
  30. vs = VideoStream(src=0).start()
  31. time.sleep(2.0)
  32. # otherwise, we are reading from a video file
  33. else:
  34. vs = cv2.VideoCapture(args["video"])
  35. cv2.namedWindow('Video stream', cv2.WINDOW_NORMAL)
  36. detector = DetectionFromFrame(args["min_area"], 0.5)
  37. while True:
  38. timer.start_frame_timer()
  39. detector.currentFrame = vs.read()
  40. detector.currentFrame = detector.currentFrame if args.get("video", None) is None else detector.currentFrame[1]
  41. # if the frame can not be grabbed, then we have reached the end of the video
  42. if detector.currentFrame is None:
  43. break
  44. # resize the frame to 500
  45. detector.currentFrame = imutils.resize(detector.currentFrame, width=500)
  46. detector.framecounter += 1
  47. if detector.framecounter > 1:
  48. cnts = detector.prepareFrame()
  49. for c in cnts:
  50. timer.start_contour_timer()
  51. bound_rect = cv2.boundingRect(c)
  52. #(x, y, w, h) = cv2.boundingRect(c)
  53. #initBB2 =(x,y,w,h)
  54. prott1 = r'ML-Models/MobileNetSSD_deploy.prototxt'
  55. prott2 = r'ML-Models/MobileNetSSD_deploy.caffemodel'
  56. net = cv2.dnn.readNetFromCaffe(prott1, prott2)
  57. #trackbox = detector.currentFrame[y:y+h, x:x+w]boundRect[1]
  58. trackbox = detector.currentFrame[bound_rect[1]:bound_rect[1]+bound_rect[3],
  59. bound_rect[0]:bound_rect[0]+bound_rect[2]]
  60. trackbox = cv2.resize(trackbox, (224, 224))
  61. #cv2.imshow('image',trackbox)
  62. timer.start_detection_timer()
  63. blob = cv2.dnn.blobFromImage(cv2.resize(trackbox, (300, 300)),0.007843, (300, 300), 127.5)
  64. net.setInput(blob)
  65. detections = net.forward()
  66. for i in np.arange(0, detections.shape[2]):
  67. detector.detectConfidentiallyPeople(i, detections, bound_rect)
  68. timer.stop_detection_timer()
  69. cv2.rectangle(detector.currentFrame, (bound_rect[0], bound_rect[1]),
  70. (bound_rect[0] + bound_rect[2], bound_rect[1] + bound_rect[3]), (255, 255, 0), 1)
  71. timer.stop_contour_timer()
  72. # show the frame and record if the user presses a key
  73. cv2.imshow("Video stream", detector.currentFrame)
  74. key = cv2.waitKey(1) & 0xFF
  75. # if the `q` key is pressed, break from the lop
  76. if key == ord("q"):
  77. break
  78. if key == ord("d"):
  79. detector.firstFrame = None
  80. #detector.lastFrame = detector.currentFrame
  81. timer.print_time()
  82. # finally, stop the camera/stream and close any open windows
  83. vs.stop() if args.get("video", None) is None else vs.release()
  84. cv2.destroyAllWindows()
  85. class Timer:
  86. def __init__(self):
  87. self.frame_timer = None
  88. self.contour_timer = None
  89. self.detection_timer = None
  90. self.contour_time = []
  91. self.detection_time = []
  92. def start_frame_timer(self):
  93. self.frame_timer = time.time()
  94. def get_frame_time(self):
  95. return time.time() - self.frame_timer
  96. def start_contour_timer(self):
  97. self.contour_timer = time.time()
  98. def stop_contour_timer(self):
  99. self.contour_time.append(time.time() - self.contour_timer)
  100. def start_detection_timer(self):
  101. self.detection_timer = time.time()
  102. def stop_detection_timer(self):
  103. self.detection_time.append(time.time() - self.detection_timer)
  104. def print_time(self):
  105. average_contour = 0 if not self.contour_time else sum(self.contour_time)/float(len(self.contour_time))
  106. average_detection = 0 if not self.detection_time else sum(self.detection_time)/float(len(self.detection_time))
  107. median_contour = 0 if not self.contour_time else median(self.contour_time)
  108. median_detection = 0 if not self.detection_time else median(self.detection_time)
  109. total_contour = sum(self.contour_time)
  110. total_detection = sum(self.detection_time)
  111. print("Time for Frame: {:.2f}. Contour Total: {:.2f}. Contour Median: {:.2f}. Contour Average: {:.2f}. Detection Total: {:.2f}. Detection Median: {:.2f}. Detection Average: {:.2f}. ".format(
  112. self.get_frame_time(), total_contour, median_contour, average_contour, total_detection, median_detection, average_detection))
  113. #print("Contour Times:" + str(timer.contour_time))
  114. #print("Detection Times:" + str(timer.detection_time))
  115. self.contour_time = []
  116. self.detection_time = []
  117. class DetectionFromFrame:
  118. def __init__(self, min_size, confidence):
  119. self.min_size = min_size
  120. self.confidence_level = confidence
  121. self.firstFrame = None
  122. self.currentFrame = None
  123. self.initBB2 = None
  124. self.fps = None
  125. self.differ = None
  126. self.now = ''
  127. self.framecounter = 0
  128. self.people_count_total = 0
  129. def prepareFrame(self):
  130. gray = cv2.cvtColor(self.currentFrame, cv2.COLOR_BGR2GRAY)
  131. gray = cv2.GaussianBlur(gray, (21, 21), 0)
  132. # if the first frame is None, initialize it
  133. if self.firstFrame is None:
  134. self.firstFrame = gray
  135. return []
  136. # compute the absolute difference between the current frame and first frame
  137. frameDelta = cv2.absdiff(self.firstFrame, gray)
  138. thresh = cv2.threshold(frameDelta, 25, 255, cv2.THRESH_BINARY)[1]
  139. #debug
  140. """if VISUAL_DEBUG:
  141. cv2.imshow("debug image", thresh)
  142. cv2.waitKey(0)
  143. cv2.destroyWindow("debug image")
  144. #cv2.destroyWindow("threshhold image")"""
  145. # dilate the thresholded image to fill in holes
  146. thresh = cv2.dilate(thresh, None, iterations=2)
  147. # find contours on thresholded image
  148. thresh = np.uint8(thresh)
  149. cnts, _ = cv2.findContours(thresh.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
  150. return cnts
  151. def detectConfidentiallyPeople(self, i, detections, bound_rect):
  152. #CLASSES = ["person"]
  153. detected_color = (0, 255, 0)
  154. #COLORS = np.random.uniform(0, 255, size=(len(CLASSES), 3))
  155. confidence = detections[0, 0, i, 2]
  156. if confidence > self.confidence_level:
  157. # extract the index of the class label from the `detections`, then compute the (x, y)-coordinates of
  158. # the bounding box for the object
  159. #idx = int(detections[0, 0, i, 1])
  160. #box = detections[0, 0, i, 3:7] * np.array([bound_rect[2], bound_rect[3], bound_rect[2], bound_rect[3]])
  161. #(startX, startY, endX, endY) = box.astype("int")
  162. # draw the prediction on the frame
  163. #label = "{}: {:.2f}%".format(CLASSES[idx], confidence * 100)
  164. label = "{:.2f}%".format(confidence * 100)
  165. #cv2.rectangle(frame, (startX, startY), (endX, endY), COLORS[idx], 2)
  166. cv2.rectangle(self.currentFrame, (bound_rect[0], bound_rect[1]),
  167. (bound_rect[0] + bound_rect[2], bound_rect[1] + bound_rect[3]), detected_color, 3)
  168. y = bound_rect[1] - 15 if bound_rect[1] - 15 > 15 else bound_rect[1] + 15
  169. #cv2.putText(frame, label, (startX, y), cv2.FONT_HERSHEY_SIMPLEX, 0.5, COLORS[idx], 2)
  170. cv2.putText(self.currentFrame, label, (bound_rect[0], bound_rect[1]-5), cv2.FONT_HERSHEY_SIMPLEX, 0.3, detected_color, 1)
  171. #cv2.imshow("Video stream", self.currentFrame)
  172. #print("Person found")
  173. if __name__ == "__main__":
  174. main()