3636#os.environ["DEPTHAI_LEVEL"] = "debug"
3737
3838import cv2
39+ import numpy as np
3940import argparse
4041import collections
4142import time
@@ -80,6 +81,8 @@ def socket_type_pair(arg):
8081 help = "Path to custom camera tuning database" )
8182parser .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
8487parser .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
179182cam = {}
180183xout = {}
184+ xout_raw = {}
185+ streams = []
181186for 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+
209224if 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 ("\n Saving:" , 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 ("\r FPS:" ,
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