Skip to content

Commit cba3c39

Browse files
committed
Rough rework to fit module format
1 parent 2391e93 commit cba3c39

File tree

1 file changed

+63
-117
lines changed

1 file changed

+63
-117
lines changed

modules/picamimx500.py

Lines changed: 63 additions & 117 deletions
Original file line numberDiff line numberDiff line change
@@ -15,18 +15,19 @@
1515

1616

1717
class 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):
3637
class 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

212203
if __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

Comments
 (0)