Skip to content

Commit c4b58d6

Browse files
committed
cam_test: add -raw for streaming/saving raw frames (+ISP YUV)
1 parent 5004cc7 commit c4b58d6

File tree

1 file changed

+56
-20
lines changed

1 file changed

+56
-20
lines changed

utilities/cam_test.py

Lines changed: 56 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@
3636
#os.environ["DEPTHAI_LEVEL"] = "debug"
3737

3838
import cv2
39+
import numpy as np
3940
import argparse
4041
import collections
4142
import time
@@ -80,6 +81,8 @@ def socket_type_pair(arg):
8081
help="Path to custom camera tuning database")
8182
parser.add_argument('-d', '--device', default="", type=str,
8283
help="Optional MX ID of the device to connect to.")
84+
parser.add_argument('-raw', '--enable-raw', default=False, action="store_true",
85+
help='Enable the RAW camera streams')
8386

8487
parser.add_argument('-ctimeout', '--connection-timeout', default=30000,
8588
help="Connection timeout in ms. Default: %(default)s (sets DEPTHAI_CONNECTION_TIMEOUT environment variable)")
@@ -178,9 +181,12 @@ def get(self):
178181

179182
cam = {}
180183
xout = {}
184+
xout_raw = {}
185+
streams = []
181186
for c in cam_list:
182187
xout[c] = pipeline.createXLinkOut()
183188
xout[c].setStreamName(c)
189+
streams.append(c)
184190
if cam_type_color[c]:
185191
cam[c] = pipeline.createColorCamera()
186192
cam[c].setResolution(color_res_opts[args.color_resolution])
@@ -206,6 +212,15 @@ def get(self):
206212
cam[c].setFps(args.fps)
207213
cam[c].setIsp3aFps(args.isp3afps)
208214

215+
if args.enable_raw:
216+
raw_name = 'raw_' + c
217+
xout_raw[c] = pipeline.create(dai.node.XLinkOut)
218+
xout_raw[c].setStreamName(raw_name)
219+
if args.enable_raw:
220+
streams.append(raw_name)
221+
cam[c].raw.link(xout_raw[c].input)
222+
# to be added cam[c].setRawOutputPacked(False)
223+
209224
if args.camera_tuning:
210225
pipeline.setCameraTuningBlobPath(str(args.camera_tuning))
211226

@@ -232,6 +247,8 @@ def exit_cleanly(signum, frame):
232247
print('auto ' if p.hasAutofocus else 'fixed', '- ', end='')
233248
print(*[type.name for type in p.supportedTypes])
234249
cam_name[p.socket.name] = p.sensorName
250+
if args.enable_raw:
251+
cam_name['raw_'+p.socket.name] = p.sensorName
235252

236253
print('USB speed:', device.getUsbSpeed().name)
237254

@@ -240,7 +257,7 @@ def exit_cleanly(signum, frame):
240257
q = {}
241258
fps_host = {} # FPS computed based on the time we receive frames in app
242259
fps_capt = {} # FPS computed based on capture timestamps from device
243-
for c in cam_list:
260+
for c in streams:
244261
q[c] = device.getOutputQueue(name=c, maxSize=4, blocking=False)
245262
# The OpenCV window resize may produce some artifacts
246263
if args.resizable_windows:
@@ -299,7 +316,7 @@ def exit_cleanly(signum, frame):
299316

300317
capture_list = []
301318
while True:
302-
for c in cam_list:
319+
for c in streams:
303320
try:
304321
pkt = q[c].tryGet()
305322
except Exception as e:
@@ -308,25 +325,44 @@ def exit_cleanly(signum, frame):
308325
if pkt is not None:
309326
fps_host[c].update()
310327
fps_capt[c].update(pkt.getTimestamp().total_seconds())
328+
width, height = pkt.getWidth(), pkt.getHeight()
311329
frame = pkt.getCvFrame()
312-
if c in capture_list:
313-
width, height = pkt.getWidth(), pkt.getHeight()
314-
capture_file_name = ('capture_' + c + '_' + cam_name[cam_socket_opts[c].name]
315-
+ '_' + str(width) + 'x' + str(height)
316-
+ '_exp_' +
317-
str(int(
318-
pkt.getExposureTime().total_seconds()*1e6))
319-
+ '_iso_' + str(pkt.getSensitivity())
320-
+ '_lens_' +
321-
str(pkt.getLensPosition())
322-
+ '_' + capture_time
323-
+ '_' + str(pkt.getSequenceNum())
324-
+ ".png"
325-
)
326-
print("\nSaving:", capture_file_name)
327-
cv2.imwrite(capture_file_name, frame)
330+
capture = c in capture_list
331+
if capture:
332+
capture_file_info = ('capture_' + c + '_' + cam_name[c]
333+
+ '_' + str(width) + 'x' + str(height)
334+
+ '_exp_' + str(int(pkt.getExposureTime().total_seconds()*1e6))
335+
+ '_iso_' + str(pkt.getSensitivity())
336+
+ '_lens_' + str(pkt.getLensPosition())
337+
+ '_' + capture_time
338+
+ '_' + str(pkt.getSequenceNum())
339+
)
328340
capture_list.remove(c)
329-
341+
print()
342+
if c.startswith('raw_'):
343+
if capture:
344+
filename = capture_file_info + '_10bit.bw'
345+
print('Saving:', filename)
346+
frame.tofile(filename)
347+
# Full range for display, use bits [15:6] of the 16-bit pixels
348+
frame = frame * (1 << 6)
349+
# Debayer color for preview/png
350+
if cam_type_color[c.split('_')[-1]]:
351+
# See this for the ordering, at the end of page:
352+
# https://docs.opencv.org/4.5.1/de/d25/imgproc_color_conversions.html
353+
# TODO add bayer order to ImgFrame getType()
354+
frame = cv2.cvtColor(frame, cv2.COLOR_BayerGB2BGR)
355+
else:
356+
# Save YUV too, but only when RAW is also enabled (for tuning purposes)
357+
if capture and args.enable_raw:
358+
payload = pkt.getData()
359+
filename = capture_file_info + '_P420.yuv'
360+
print('Saving:', filename)
361+
payload.tofile(filename)
362+
if capture:
363+
filename = capture_file_info + '.png'
364+
print('Saving:', filename)
365+
cv2.imwrite(filename, frame)
330366
cv2.imshow(c, frame)
331367
print("\rFPS:",
332368
*["{:6.2f}|{:6.2f}".format(fps_host[c].get(),
@@ -337,7 +373,7 @@ def exit_cleanly(signum, frame):
337373
if key == ord('q'):
338374
break
339375
elif key == ord('c'):
340-
capture_list = cam_list.copy()
376+
capture_list = streams.copy()
341377
capture_time = time.strftime('%Y%m%d_%H%M%S')
342378
elif key == ord('t'):
343379
print("Autofocus trigger (and disable continuous)")

0 commit comments

Comments
 (0)