Advertisement
Guest User

age-detection

a guest
Oct 1st, 2022
418
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 9.49 KB | None | 0 0
  1. from MultiMsgSync import TwoStageHostSeqSync
  2. import blobconverter
  3. import cv2
  4. import depthai as dai
  5. import numpy as np
  6. from pathlib import Path
  7.  
  8. def frame_norm(frame, bbox):
  9. normVals = np.full(len(bbox), frame.shape[0])
  10. normVals[::2] = frame.shape[1]
  11. return (np.clip(np.array(bbox), 0, 1) * normVals).astype(int)
  12.  
  13. def create_pipeline(stereo):
  14. pipeline = dai.Pipeline()
  15.  
  16. print("Creating Color Camera...")
  17. cam = pipeline.create(dai.node.ColorCamera)
  18. cam.setPreviewSize(1072, 1072)
  19. cam.setResolution(dai.ColorCameraProperties.SensorResolution.THE_1080_P)
  20. cam.setInterleaved(False)
  21. cam.setBoardSocket(dai.CameraBoardSocket.RGB)
  22.  
  23. # Workaround: remove in 2.18, use `cam.setPreviewNumFramesPool(10)`
  24. # This manip uses 15*3.5 MB => 52 MB of RAM.
  25. copy_manip = pipeline.create(dai.node.ImageManip)
  26. copy_manip.setNumFramesPool(15)
  27. copy_manip.setMaxOutputFrameSize(1072 * 1072 * 3)
  28. cam.preview.link(copy_manip.inputImage)
  29.  
  30. cam_xout = pipeline.create(dai.node.XLinkOut)
  31. cam_xout.setStreamName("color")
  32. copy_manip.out.link(cam_xout.input)
  33.  
  34. # ImageManip will resize the frame before sending it to the Face detection NN node
  35. face_det_manip = pipeline.create(dai.node.ImageManip)
  36. face_det_manip.initialConfig.setResize(300, 300)
  37. face_det_manip.initialConfig.setFrameType(dai.RawImgFrame.Type.RGB888p)
  38. copy_manip.out.link(face_det_manip.inputImage)
  39.  
  40. if stereo:
  41. monoLeft = pipeline.create(dai.node.MonoCamera)
  42. monoLeft.setResolution(dai.MonoCameraProperties.SensorResolution.THE_400_P)
  43. monoLeft.setBoardSocket(dai.CameraBoardSocket.LEFT)
  44.  
  45. monoRight = pipeline.create(dai.node.MonoCamera)
  46. monoRight.setResolution(dai.MonoCameraProperties.SensorResolution.THE_400_P)
  47. monoRight.setBoardSocket(dai.CameraBoardSocket.RIGHT)
  48.  
  49. stereo = pipeline.create(dai.node.StereoDepth)
  50. stereo.setDefaultProfilePreset(dai.node.StereoDepth.PresetMode.HIGH_DENSITY)
  51. stereo.setDepthAlign(dai.CameraBoardSocket.RGB)
  52. monoLeft.out.link(stereo.left)
  53. monoRight.out.link(stereo.right)
  54.  
  55. # Spatial Detection network if OAK-D
  56. print("OAK-D detected, app will display spatial coordiantes")
  57. face_det_nn = pipeline.create(dai.node.MobileNetSpatialDetectionNetwork)
  58. face_det_nn.setBoundingBoxScaleFactor(0.8)
  59. face_det_nn.setDepthLowerThreshold(100)
  60. face_det_nn.setDepthUpperThreshold(5000)
  61. stereo.depth.link(face_det_nn.inputDepth)
  62. else: # Detection network if OAK-1
  63. print("OAK-1 detected, app won't display spatial coordiantes")
  64. face_det_nn = pipeline.create(dai.node.MobileNetDetectionNetwork)
  65.  
  66. face_det_nn.setConfidenceThreshold(0.5)
  67. face_det_nn.setBlobPath(blobconverter.from_zoo(name="face-detection-retail-0004", shaves=6))
  68. face_det_nn.input.setQueueSize(1)
  69. face_det_manip.out.link(face_det_nn.input)
  70.  
  71. # Send face detections to the host (for bounding boxes)
  72. face_det_xout = pipeline.create(dai.node.XLinkOut)
  73. face_det_xout.setStreamName("detection")
  74. face_det_nn.out.link(face_det_xout.input)
  75.  
  76. # Script node will take the output from the face detection NN as an input and set ImageManipConfig
  77. # to the 'recognition_manip' to crop the initial frame
  78. image_manip_script = pipeline.create(dai.node.Script)
  79. face_det_nn.out.link(image_manip_script.inputs['face_det_in'])
  80.  
  81. # Remove in 2.18 and use `imgFrame.getSequenceNum()` in Script node
  82. face_det_nn.passthrough.link(image_manip_script.inputs['passthrough'])
  83.  
  84. copy_manip.out.link(image_manip_script.inputs['preview'])
  85.  
  86. image_manip_script.setScript("""
  87. import time
  88. msgs = dict()
  89. def add_msg(msg, name, seq = None):
  90. global msgs
  91. if seq is None:
  92. seq = msg.getSequenceNum()
  93. seq = str(seq)
  94. # node.warn(f"New msg {name}, seq {seq}")
  95. # Each seq number has it's own dict of msgs
  96. if seq not in msgs:
  97. msgs[seq] = dict()
  98. msgs[seq][name] = msg
  99. # To avoid freezing (not necessary for this ObjDet model)
  100. if 15 < len(msgs):
  101. node.warn(f"Removing first element! len {len(msgs)}")
  102. msgs.popitem() # Remove first element
  103. def get_msgs():
  104. global msgs
  105. seq_remove = [] # Arr of sequence numbers to get deleted
  106. for seq, syncMsgs in msgs.items():
  107. seq_remove.append(seq) # Will get removed from dict if we find synced msgs pair
  108. # node.warn(f"Checking sync {seq}")
  109. # Check if we have both detections and color frame with this sequence number
  110. if len(syncMsgs) == 2: # 1 frame, 1 detection
  111. for rm in seq_remove:
  112. del msgs[rm]
  113. # node.warn(f"synced {seq}. Removed older sync values. len {len(msgs)}")
  114. return syncMsgs # Returned synced msgs
  115. return None
  116. def correct_bb(bb):
  117. if bb.xmin < 0: bb.xmin = 0.001
  118. if bb.ymin < 0: bb.ymin = 0.001
  119. if bb.xmax > 1: bb.xmax = 0.999
  120. if bb.ymax > 1: bb.ymax = 0.999
  121. return bb
  122. while True:
  123. time.sleep(0.001) # Avoid lazy looping
  124. preview = node.io['preview'].tryGet()
  125. if preview is not None:
  126. add_msg(preview, 'preview')
  127. face_dets = node.io['face_det_in'].tryGet()
  128. if face_dets is not None:
  129. # TODO: in 2.18.0.0 use face_dets.getSequenceNum()
  130. passthrough = node.io['passthrough'].get()
  131. seq = passthrough.getSequenceNum()
  132. add_msg(face_dets, 'dets', seq)
  133. sync_msgs = get_msgs()
  134. if sync_msgs is not None:
  135. img = sync_msgs['preview']
  136. dets = sync_msgs['dets']
  137. for i, det in enumerate(dets.detections):
  138. cfg = ImageManipConfig()
  139. correct_bb(det)
  140. cfg.setCropRect(det.xmin, det.ymin, det.xmax, det.ymax)
  141. # node.warn(f"Sending {i + 1}. det. Seq {seq}. Det {det.xmin}, {det.ymin}, {det.xmax}, {det.ymax}")
  142. cfg.setResize(200, 200)
  143. cfg.setKeepAspectRatio(False)
  144. node.io['manip_cfg'].send(cfg)
  145. node.io['manip_img'].send(img)
  146. """)
  147.  
  148. recognition_manip = pipeline.create(dai.node.ImageManip)
  149. recognition_manip.initialConfig.setResize(200, 200)
  150. recognition_manip.inputConfig.setWaitForMessage(True)
  151. image_manip_script.outputs['manip_cfg'].link(recognition_manip.inputConfig)
  152. image_manip_script.outputs['manip_img'].link(recognition_manip.inputImage)
  153.  
  154. # Second stange recognition NN
  155. print("Creating recognition Neural Network...")
  156. recognition_nn = pipeline.create(dai.node.NeuralNetwork)
  157. #recognition_nn.setBlobPath(blobconverter.from_zoo(name="age-gender-recognition-retail-0013", shaves=6))
  158. recognition_nn.setBlobPath(str(Path("model.blob").resolve().absolute()))
  159. recognition_manip.out.link(recognition_nn.input)
  160.  
  161. recognition_xout = pipeline.create(dai.node.XLinkOut)
  162. recognition_xout.setStreamName("recognition")
  163. recognition_nn.out.link(recognition_xout.input)
  164.  
  165. return pipeline
  166.  
  167. with dai.Device() as device:
  168. stereo = 1 < len(device.getConnectedCameras())
  169. device.startPipeline(create_pipeline(stereo))
  170.  
  171. sync = TwoStageHostSeqSync()
  172. queues = {}
  173. # Create output queues
  174. for name in ["color", "detection", "recognition"]:
  175. queues[name] = device.getOutputQueue(name)
  176.  
  177. while True:
  178. for name, q in queues.items():
  179. # Add all msgs (color frames, object detections and recognitions) to the Sync class.
  180. if q.has():
  181. sync.add_msg(q.get(), name)
  182.  
  183. msgs = sync.get_msgs()
  184. if msgs is not None:
  185. frame = msgs["color"].getCvFrame()
  186. detections = msgs["detection"].detections
  187. recognitions = msgs["recognition"]
  188.  
  189. for i, detection in enumerate(detections):
  190. bbox = frame_norm(frame, (detection.xmin, detection.ymin, detection.xmax, detection.ymax))
  191.  
  192. # Decoding of recognition results
  193. rec = recognitions[i]
  194. age = np.array(rec.getLayerFp16('age'))
  195. # gender = np.squeeze(np.array(rec.getLayerFp16('prob')))
  196. # gender_str = "female" if gender[0] > gender[1] else "male"
  197.  
  198. cv2.rectangle(frame, (bbox[0], bbox[1]), (bbox[2], bbox[3]), (10, 245, 10), 2)
  199. y = (bbox[1] + bbox[3]) // 2
  200. cv2.putText(frame, str(age), (bbox[0], y), cv2.FONT_HERSHEY_TRIPLEX, 1.5, (0, 0, 0), 8)
  201. cv2.putText(frame, str(age), (bbox[0], y), cv2.FONT_HERSHEY_TRIPLEX, 1.5, (255, 255, 255), 2)
  202. # cv2.putText(frame, gender_str, (bbox[0], y + 30), cv2.FONT_HERSHEY_TRIPLEX, 1.5, (0, 0, 0), 8)
  203. # cv2.putText(frame, gender_str, (bbox[0], y + 30), cv2.FONT_HERSHEY_TRIPLEX, 1.5, (255, 255, 255), 2)
  204. # if stereo:
  205. # # You could also get detection.spatialCoordinates.x and detection.spatialCoordinates.y coordinates
  206. # coords = "Z: {:.2f} m".format(detection.spatialCoordinates.z/1000)
  207. # cv2.putText(frame, coords, (bbox[0], y + 60), cv2.FONT_HERSHEY_TRIPLEX, 1, (0, 0, 0), 8)
  208. # cv2.putText(frame, coords, (bbox[0], y + 60), cv2.FONT_HERSHEY_TRIPLEX, 1, (255, 255, 255), 2)
  209.  
  210. cv2.imshow("Camera", frame)
  211. if cv2.waitKey(1) == ord('q'):
  212. break
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement