1515
1616
1717class Detection :
18- def __init__ (self , coords , category , conf , metadata ):
18+ def __init__ (self , imx500 , picam2 , selfref , coords , category , conf , metadata ):
1919 """Create a Detection object, recording the bounding box, category and confidence."""
2020 self .category = category
2121 self .conf = conf
2222 self .box = imx500 .convert_inference_coords (coords , metadata , picam2 )
23+ self .piCamImx500 = selfref
2324 def display (self ):
24- label = f"{ PiCamImx500 .get_labels ()[int (self .category )]} ({ self .conf :.2f} %): { self .box } "
25+ label = f"{ self . piCamImx500 .get_labels ()[int (self .category )]} ({ self .conf :.2f} %): { self .box } "
2526 print (label )
2627 print ("" )
2728 def json_out (self ):
2829 return {
29- 'category' : PiCamImx500 .get_labels ()[int (self .category )],
30+ 'category' : self . piCamImx500 .get_labels ()[int (self .category )],
3031 'confidence' : self .conf ,
3132 'box' : self .box
3233 }
@@ -36,84 +37,77 @@ def json_out(self):
3637class PiCamImx500 :
3738 def __init__ (self , ** kwargs ):
3839 self .last_detections = []
39- # self.translator = kwargs.get('translator', None)
40- # self.service = kwargs.get('service', 'pyttsx3')
41- # if self.service == 'elevenlabs':
42- # self.init_elevenlabs(kwargs.get('voice_id', ''))
43- # else:
44- # self.init_pyttsx3()
45- # # Set subscribers
46- # pub.subscribe(self.speak, 'tts')
47-
48- # def speak(self, msg):
49- # if self.service == 'elevenlabs':
50- # self.speak_elevenlabs(msg)
51- # else:
52- # self.speak_pyttsx3(msg)#
53- #
54-
55- def detect (self , captures ):
40+ self .last_results = []
41+
42+ self .args = PiCamImx500 .get_args ()
43+
5644 # This must be called before instantiation of Picamera2
57- imx500 = IMX500 (args .model )
58- intrinsics = imx500 .network_intrinsics
59- if not intrinsics :
60- intrinsics = NetworkIntrinsics ()
61- intrinsics .task = "object detection"
62- elif intrinsics .task != "object detection" :
45+ self . imx500 = IMX500 (self . args .model )
46+ self . intrinsics = self . imx500 .network_intrinsics
47+ if not self . intrinsics :
48+ self . intrinsics = NetworkIntrinsics ()
49+ self . intrinsics .task = "object detection"
50+ elif self . intrinsics .task != "object detection" :
6351 print ("Network is not an object detection task" , file = sys .stderr )
6452 exit ()
6553
66- # Override intrinsics from args
67- for key , value in vars (args ).items ():
54+ # Override self. intrinsics from self. args
55+ for key , value in vars (self . args ).items ():
6856 if key == 'labels' and value is not None :
6957 with open (value , 'r' ) as f :
70- intrinsics .labels = f .read ().splitlines ()
71- elif hasattr (intrinsics , key ) and value is not None :
72- setattr (intrinsics , key , value )
58+ self . intrinsics .labels = f .read ().splitlines ()
59+ elif hasattr (self . intrinsics , key ) and value is not None :
60+ setattr (self . intrinsics , key , value )
7361
7462 # Defaults
75- if intrinsics .labels is None :
63+ if self . intrinsics .labels is None :
7664 with open ("assets/coco_labels.txt" , "r" ) as f :
77- intrinsics .labels = f .read ().splitlines ()
78- intrinsics .update_with_defaults ()
65+ self . intrinsics .labels = f .read ().splitlines ()
66+ self . intrinsics .update_with_defaults ()
7967
80- if args .print_intrinsics :
81- print (intrinsics )
82- exit ()
68+ # if self. args.print_self.intrinsics :
69+ # print(self. intrinsics)
70+ # exit()
8371
84- picam2 = Picamera2 (imx500 .camera_num )
85- config = picam2 .create_preview_configuration (controls = {"FrameRate" : intrinsics .inference_rate }, buffer_count = 12 , transform = Transform (vflip = True , hflip = True ))
72+ self . picam2 = Picamera2 (self . imx500 .camera_num )
73+ config = self . picam2 .create_preview_configuration (controls = {"FrameRate" : self . intrinsics .inference_rate }, buffer_count = 12 , transform = Transform (vflip = False , hflip = False ))
8674
87- imx500 .show_network_fw_progress_bar ()
88- picam2 .start (config , show_preview = False )
75+ self . imx500 .show_network_fw_progress_bar ()
76+ self . picam2 .start (config , show_preview = False )
8977
90- if intrinsics .preserve_aspect_ratio :
91- imx500 .set_auto_aspect_ratio ()
78+ if self . intrinsics .preserve_aspect_ratio :
79+ self . imx500 .set_auto_aspect_ratio ()
9280
93- last_results = None
94- mycam = PiCamImx500 ()
95- picam2 .pre_callback = PiCamImx500 .draw_detections
81+ self .picam2 .pre_callback = self .draw_detections
9682
83+ pub .subscribe (self .scan , 'vision:detect' )
84+
85+ def scan (self , captures = 1 ):
9786 json_array = []
9887 for i in range (captures ):
99- last_results = mycam .parse_detections (picam2 .capture_metadata ())
100- for i in last_results :
101- this_capture = [obj .json_out () for obj in last_results ]
102- json_array .push (this_capture )
88+ self .last_results = self .parse_detections (self .picam2 .capture_metadata ())
89+ for i in self .last_results :
90+ this_capture = [obj .json_out () for obj in self .last_results ]
91+ if captures > 1 :
92+ json_array = json_array + [this_capture ]
93+ else :
94+ json_array = this_capture
95+
96+ pub .sendMessage ('vision:detections' , data = json_array )
10397 return json_array
10498
10599 def parse_detections (self , metadata : dict ):
106100 """Parse the output tensor into a number of detected objects, scaled to the ISP out."""
107- bbox_normalization = intrinsics .bbox_normalization
108- threshold = args .threshold
109- iou = args .iou
110- max_detections = args .max_detections
101+ bbox_normalization = self . intrinsics .bbox_normalization
102+ threshold = self . args .threshold
103+ iou = self . args .iou
104+ max_detections = self . args .max_detections
111105
112- np_outputs = imx500 .get_outputs (metadata , add_batch = True )
113- input_w , input_h = imx500 .get_input_size ()
106+ np_outputs = self . imx500 .get_outputs (metadata , add_batch = True )
107+ input_w , input_h = self . imx500 .get_input_size ()
114108 if np_outputs is None :
115109 return self .last_detections
116- if intrinsics .postprocess == "nanodet" :
110+ if self . intrinsics .postprocess == "nanodet" :
117111 boxes , scores , classes = \
118112 postprocess_nanodet_detection (outputs = np_outputs [0 ], conf = threshold , iou_thres = iou ,
119113 max_out_dets = max_detections )[0 ]
@@ -128,29 +122,26 @@ def parse_detections(self, metadata: dict):
128122 boxes = zip (* boxes )
129123
130124 self .last_detections = [
131- Detection (box , category , score , metadata )
125+ Detection (self . imx500 , self . picam2 , self , box , category , score , metadata )
132126 for box , score , category in zip (boxes , scores , classes )
133127 if score > threshold
134128 ]
135129 return self .last_detections
136130
137- @staticmethod
138131 @lru_cache
139- def get_labels ():
140- labels = intrinsics .labels
132+ def get_labels (self ):
133+ labels = self . intrinsics .labels
141134
142- if intrinsics .ignore_dash_labels :
135+ if self . intrinsics .ignore_dash_labels :
143136 labels = [label for label in labels if label and label != "-" ]
144137 return labels
145138
146-
147- @staticmethod
148- def draw_detections (request , stream = "main" ):
139+ def draw_detections (self , request , stream = "main" ):
149140 """Draw the detections for this request onto the ISP output."""
150- detections = last_results
141+ detections = self . last_results
151142 if detections is None :
152143 return
153- labels = PiCamImx500 .get_labels ()
144+ labels = self .get_labels ()
154145 with MappedArray (request , stream ) as m :
155146 for detection in detections :
156147 x , y , w , h = detection .box
@@ -181,8 +172,8 @@ def draw_detections(request, stream="main"):
181172 # Draw detection box
182173 cv2 .rectangle (m .array , (x , y ), (x + w , y + h ), (0 , 255 , 0 , 0 ), thickness = 2 )
183174
184- if intrinsics .preserve_aspect_ratio :
185- b_x , b_y , b_w , b_h = imx500 .get_roi_scaled (request )
175+ if self . intrinsics .preserve_aspect_ratio :
176+ b_x , b_y , b_w , b_h = self . imx500 .get_roi_scaled (request )
186177 color = (255 , 0 , 0 ) # red
187178 cv2 .putText (m .array , "ROI" , (b_x + 5 , b_y + 15 ), cv2 .FONT_HERSHEY_SIMPLEX , 0.5 , color , 1 )
188179 cv2 .rectangle (m .array , (b_x , b_y ), (b_x + b_w , b_y + b_h ), (255 , 0 , 0 , 0 ))
@@ -204,58 +195,13 @@ def get_args():
204195 help = "preserve the pixel aspect ratio of the input tensor" )
205196 parser .add_argument ("--labels" , type = str ,
206197 help = "Path to the labels file" )
207- parser .add_argument ("--print-intrinsics" , action = "store_true" ,
198+ parser .add_argument ("--print-self. intrinsics" , action = "store_true" ,
208199 help = "Print JSON network_intrinsics then exit" )
209200 return parser .parse_args ()
210201
211202
212203if __name__ == "__main__" :
213204 mycam = PiCamImx500 ()
214- args = PiCamImx500 .get_args ()
215-
216- # This must be called before instantiation of Picamera2
217- imx500 = IMX500 (args .model )
218- intrinsics = imx500 .network_intrinsics
219- if not intrinsics :
220- intrinsics = NetworkIntrinsics ()
221- intrinsics .task = "object detection"
222- elif intrinsics .task != "object detection" :
223- print ("Network is not an object detection task" , file = sys .stderr )
224- exit ()
225-
226- # Override intrinsics from args
227- for key , value in vars (args ).items ():
228- if key == 'labels' and value is not None :
229- with open (value , 'r' ) as f :
230- intrinsics .labels = f .read ().splitlines ()
231- elif hasattr (intrinsics , key ) and value is not None :
232- setattr (intrinsics , key , value )
233-
234- # Defaults
235- if intrinsics .labels is None :
236- with open ("assets/coco_labels.txt" , "r" ) as f :
237- intrinsics .labels = f .read ().splitlines ()
238- intrinsics .update_with_defaults ()
239-
240- if args .print_intrinsics :
241- print (intrinsics )
242- exit ()
243-
244- picam2 = Picamera2 (imx500 .camera_num )
245- config = picam2 .create_preview_configuration (controls = {"FrameRate" : intrinsics .inference_rate }, buffer_count = 12 , transform = Transform (vflip = False , hflip = False ))
246-
247- imx500 .show_network_fw_progress_bar ()
248- picam2 .start (config , show_preview = False )
249-
250- if intrinsics .preserve_aspect_ratio :
251- imx500 .set_auto_aspect_ratio ()
252-
253- last_results = None
254205
255- picam2 .pre_callback = PiCamImx500 .draw_detections
256- while True :
257-
258- last_results = mycam .parse_detections (picam2 .capture_metadata ())
259- for i in last_results :
260- json_array = [obj .json_out () for obj in last_results ]
261- print (json_array )
206+ # while True:
207+ print (mycam .scan (1 ))
0 commit comments