def __init__(self, fname, frame_rate, compress=True): self.fname = fname self.frame_rate = frame_rate #setup option for AVIRecorder if compress: chosenAviType = AviType.MJPG option = PySpin.MJPGOption() option.frameRate = self.frame_rate option.quality = 75 else: chosenAviType = AviType.UNCOMPRESSED option = PySpin.AVIOption() option.frameRate = self.frame_rate #create instance for recorder self.rec = PySpin.SpinVideo() if os.path.exists(self.fname + '-0000.avi'): print("File already exists, saving with timestamp") timestamp = time.strftime('%H%M%S', time.localtime()) self.fname = self.fname + timestamp #create file try: self.rec.Open(self.fname, option) except PySpin.SpinnakerException as ex: print("Error: %s" % ex)
def run(self): """ """ if self.filename.suffix == '.mp4': container = PySpin.MJPGOption() elif self.filename.suffix == '.avi': container = PySpin.AVIOption() else: container = PySpin.H264Option() container.bitrate = self.bitrate container.height = self.height container.width = self.width container.frameRate = self.framerate # initialize the writer writer = PySpin.SpinVideo() writer.Open(str(self.filename), container) while self.started.value: try: image = self.q.get(timeout=False) pointer = PySpin.Image_Create(self.width, self.height, 0, 0, PySpin.PixelFormat_Mono8, image) writer.Append(pointer) except queue.Empty: continue writer.Close() return
def startCapture(self): result = 0 self.stopCaptureFlag_ = False print('*** CREATING VIDEO ***\n') try: # Retrieve device serial number for filename deviceSerialNumber = '' nodeMapTLDevice = self.camera_.GetTLDeviceNodeMap() nodeSerial = PySpin.CStringPtr( nodeMapTLDevice.GetNode('DeviceSerialNumber')) if PySpin.IsAvailable(nodeSerial) and PySpin.IsReadable( nodeSerial): deviceSerialNumber = nodeSerial.GetValue() print('Device serial number retrieved as %s...' % deviceSerialNumber) #! Set frame rate equal to the current acquisition frame rate (Hz) nodemap = self.camera_.GetNodeMap() nodeFramerate = PySpin.CFloatPtr( nodemap.GetNode('AcquisitionFrameRate')) if (not PySpin.IsAvailable(nodeFramerate)) or ( not PySpin.IsReadable(nodeFramerate)): print('Unable to retrieve frame rate. Aborting...') return -1 frameRateToSet = nodeFramerate.GetValue() print('Frame rate to be set to %d...' % frameRateToSet) #! Create a unique filename and configure file parameters self.aviRecorder_ = PySpin.SpinVideo() aviFilename = '%s%sSN%s.%s.%s' % ( self.captureProperties.outputPath, self.captureProperties.cameraPrefix, deviceSerialNumber, datetime.datetime.now().strftime("%Y%m%dT%H%M%S"), self.captureProperties.cameraSuffix) # use the configured options if self.captureProperties.aviType == 'UNCOMPRESSED': self.aviType_ = self.AviType.UNCOMPRESSED elif self.captureProperties.aviType == 'MJPG': self.aviType_ = self.AviType.MJPG elif self.captureProperties.aviType == 'H264': self.aviType_ = self.AviType.H264 else: print( 'Unknown aviType (', self.captureProperties.aviType, ') requested, only UNCOMPRESSED, MJPG and H264 supported') if self.aviType_ == self.AviType.UNCOMPRESSED: #aviFilename = 'SaveToAvi-Uncompressed-%s' % deviceSerialNumber option = PySpin.AVIOption() elif self.aviType_ == self.AviType.MJPG: #aviFilename = 'SaveToAvi-MJPG-%s' % (deviceSerialNumber,) option = PySpin.MJPGOption() #option.quality = 75 option.quality = self.captureProperties.MJPGQuality elif self.aviType_ == self.AviType.H264: #aviFilename = 'SaveToAvi-H264-%s' % deviceSerialNumber option = PySpin.H264Option() #option.bitrate = 1000000 option.bitrate = self.captureProperties.H264BitRate option.height = self.camera_.Height.GetValue() option.width = self.camera_.Width.GetValue() else: print('Error: Unknown AviType. Aborting...') return -1 option.frameRate = frameRateToSet self.aviRecorder_.Open(aviFilename, option) #! note that AVIRecorder takes care of the file extension print("Video is saving at %s.avi\n" % aviFilename) sNodeMap = self.camera_.GetTLStreamNodeMap() streamNode = PySpin.CIntegerPtr( sNodeMap.GetNode('StreamTotalBufferCount')) if not PySpin.IsAvailable(streamNode) or not PySpin.IsReadable( streamNode): print( 'Unable to get Stream Total Buffer Count (node retrieval). Aborting...\n' ) return False #Spinnaker::GenApi::INodeMap& sNodeMap = camera_->GetTLStreamNodeMap(); #Spinnaker::GenApi::CIntegerPtr streamNode = sNodeMap.GetNode("StreamTotalBufferCount"); self.receivedFramesCnt_ = streamNode.GetValue() self.captureOn_ = True self.processFrame() except PySpin.SpinnakerException as ex: print('Error: %s' % ex) return -1 return result
def save_list_to_avi(nodemap, nodemap_tldevice, images): """ This function prepares, saves, and cleans up an AVI video from a vector of images. :param nodemap: Device nodemap. :param nodemap_tldevice: Transport layer device nodemap. :param images: List of images to save to an AVI video. :type nodemap: INodeMap :type nodemap_tldevice: INodeMap :type images: list of ImagePtr :return: True if successful, False otherwise. :rtype: bool """ print('*** CREATING VIDEO ***') try: result = True # Retrieve device serial number for filename device_serial_number = '' node_serial = PySpin.CStringPtr( nodemap_tldevice.GetNode('DeviceSerialNumber')) if PySpin.IsAvailable(node_serial) and PySpin.IsReadable(node_serial): device_serial_number = node_serial.GetValue() print('Device serial number retrieved as %s...' % device_serial_number) # Get the current frame rate; acquisition frame rate recorded in hertz # # *** NOTES *** # The video frame rate can be set to anything; however, in order to # have videos play in real-time, the acquisition frame rate can be # retrieved from the camera. node_acquisition_framerate = PySpin.CFloatPtr( nodemap.GetNode('AcquisitionFrameRate')) if not PySpin.IsAvailable( node_acquisition_framerate) and not PySpin.IsReadable( node_acquisition_framerate): print('Unable to retrieve frame rate. Aborting...') return False framerate_to_set = node_acquisition_framerate.GetValue() print('Frame rate to be set to %d...' % framerate_to_set) # Select option and open AVI filetype with unique filename # # *** NOTES *** # Depending on the filetype, a number of settings need to be set in # an object called an option. An uncompressed option only needs to # have the video frame rate set whereas videos with MJPG or H264 # compressions should have more values set. # # Once the desired option object is configured, open the AVI file # with the option in order to create the image file. # # Note that the filename does not need to be appended to the # name of the file. This is because the AVI recorder object takes care # of the file extension automatically. # # *** LATER *** # Once all images have been added, it is important to close the file - # this is similar to many other standard file streams. avi_recorder = PySpin.SpinVideo() if chosenAviType == AviType.UNCOMPRESSED: avi_filename = 'SaveToAvi-Uncompressed-%s' % device_serial_number option = PySpin.AVIOption() option.frameRate = framerate_to_set elif chosenAviType == AviType.MJPG: avi_filename = 'SaveToAvi-MJPG-%s' % device_serial_number option = PySpin.MJPGOption() option.frameRate = framerate_to_set option.quality = 75 elif chosenAviType == AviType.H264: avi_filename = 'SaveToAvi-H264-%s' % device_serial_number option = PySpin.H264Option() option.frameRate = framerate_to_set option.bitrate = 1000000 option.height = images[0].GetHeight() option.width = images[0].GetWidth() else: print('Error: Unknown AviType. Aborting...') return False avi_recorder.Open(avi_filename, option) # Construct and save AVI video # # *** NOTES *** # Although the video file has been opened, images must be individually # appended in order to construct the video. print('Appending %d images to AVI file: %s.avi...' % (len(images), avi_filename)) for i in range(len(images)): avi_recorder.Append(images[i]) print('Appended image %d...' % i) # Close AVI file # # *** NOTES *** # Once all images have been appended, it is important to close the # AVI file. Notice that once an AVI file has been closed, no more # images can be added. avi_recorder.Close() print('Video saved at %s.avi' % avi_filename) except PySpin.SpinnakerException as ex: print('Error: %s' % ex) return False return result
def run(self): print('child: ', os.getpid()) record = False ismaster = False while True: try: msg = self.camq.get(block=False) # print(msg) try: if msg == 'InitM': ismaster = True system = PySpin.System.GetInstance() cam_list = system.GetCameras() cam = cam_list.GetBySerial(self.camID) cam.Init() cam.CounterSelector.SetValue( PySpin.CounterSelector_Counter0) cam.CounterEventSource.SetValue( PySpin.CounterEventSource_ExposureStart) cam.CounterEventActivation.SetValue( PySpin.CounterEventActivation_RisingEdge) cam.CounterTriggerSource.SetValue( PySpin.CounterTriggerSource_ExposureStart) cam.CounterTriggerActivation.SetValue( PySpin.CounterTriggerActivation_RisingEdge) cam.LineSelector.SetValue(PySpin.LineSelector_Line2) cam.V3_3Enable.SetValue(True) cam.LineSelector.SetValue(PySpin.LineSelector_Line1) cam.LineSource.SetValue( PySpin.LineSource_Counter0Active) cam.LineInverter.SetValue(False) cam.TriggerMode.SetValue(PySpin.TriggerMode_Off) cam.TriggerSource.SetValue( PySpin.TriggerSource_Software) cam.TriggerOverlap.SetValue(PySpin.TriggerOverlap_Off) cam.TriggerMode.SetValue(PySpin.TriggerMode_On) self.camq_p2read.put('done') if msg == 'InitS': system = PySpin.System.GetInstance() cam_list = system.GetCameras() cam = cam_list.GetBySerial(self.camID) cam.Init() cam.TriggerSource.SetValue(PySpin.TriggerSource_Line3) cam.TriggerOverlap.SetValue( PySpin.TriggerOverlap_ReadOut) cam.TriggerActivation.SetValue( PySpin.TriggerActivation_AnyEdge) cam.TriggerMode.SetValue(PySpin.TriggerMode_On) self.camq_p2read.put('done') elif msg == 'Release': cam.DeInit() del cam for i in self.idList: cam_list.RemoveBySerial(str(i)) system.ReleaseInstance() # Release instance self.camq_p2read.put('done') elif msg == 'recordPrep': path_base = self.camq.get() write_frame_rate = 30 s_node_map = cam.GetTLStreamNodeMap() handling_mode = PySpin.CEnumerationPtr( s_node_map.GetNode('StreamBufferHandlingMode')) if not PySpin.IsAvailable( handling_mode) or not PySpin.IsWritable( handling_mode): print( 'Unable to set Buffer Handling mode (node retrieval). Aborting...\n' ) return handling_mode_entry = handling_mode.GetEntryByName( 'OldestFirst') handling_mode.SetIntValue( handling_mode_entry.GetValue()) avi = PySpin.SpinVideo() option = PySpin.AVIOption() option.frameRate = write_frame_rate # option = PySpin.MJPGOption() # option.frameRate = write_frame_rate # option.quality = 75 print(path_base) avi.Open(path_base, option) f = open('%s_timestamps.txt' % path_base, 'w') start_time = 0 capture_duration = 0 record = True self.camq_p2read.put('done') elif msg == 'Start': cam.BeginAcquisition() if ismaster: cam.LineSelector.SetValue( PySpin.LineSelector_Line1) cam.LineSource.SetValue( PySpin.LineSource_Counter0Active) self.frm.value = 0 self.camq.get() cam.TriggerMode.SetValue(PySpin.TriggerMode_Off) bc = 0 while self.aq.value: try: image_result = cam.GetNextImage() image_result = image_result.Convert( PySpin.PixelFormat_Mono8, PySpin.HQ_LINEAR) if record: if start_time == 0: start_time = image_result.GetTimeStamp( ) else: capture_duration = image_result.GetTimeStamp( ) - start_time start_time = image_result.GetTimeStamp( ) # capture_duration = capture_duration/1000/1000 avi.Append(image_result) f.write("%s\n" % round(capture_duration)) frame = image_result.GetNDArray() cpt = self.cpt frame = frame[cpt[2]:cpt[2] + cpt[3], cpt[0]:cpt[0] + cpt[1]] self.array[ self.dlc.value][bc][0:] = frame.flatten() if ismaster: self.frm.value += 1 bc += 1 if bc >= self.bs: bc = 0 if ismaster: if self.dlc.value == 0: self.dlc.value = 1 elif self.dlc.value == 1: self.dlc.value = 2 elif self.dlc.value == 2: self.dlc.value = 0 except Exception as ex: print(ex) print(self.camID) break self.camq.get() if record: avi.Close() f.close() record = False cam.EndAcquisition() cam.TriggerMode.SetValue(PySpin.TriggerMode_On) if ismaster: self.dlc.value = 0 cam.LineSelector.SetValue( PySpin.LineSelector_Line1) cam.LineSource.SetValue( PySpin.LineSource_FrameTriggerWait) cam.LineInverter.SetValue(True) self.camq_p2read.put('done') elif msg == 'setBinning': binsize = self.camq.get(block=True) cam.BinningHorizontal.SetValue(binsize) cam.BinningVertical.SetValue(binsize) elif msg == 'exp_frmrate': exposure_time_request = self.camq.get(block=True) record_frame_rate = self.camq.get(block=True) if cam.ExposureAuto.GetAccessMode() != PySpin.RW: print( 'Unable to disable automatic exposure. Aborting...' ) continue cam.ExposureAuto.SetValue(PySpin.ExposureAuto_Off) if cam.ExposureTime.GetAccessMode() != PySpin.RW: print('Unable to set exposure time. Aborting...') continue # Ensure desired exposure time does not exceed the maximum exposure_time_to_set = floor(1 / record_frame_rate * 1000 * 1000) if exposure_time_request <= exposure_time_to_set: exposure_time_to_set = exposure_time_request max_exposure = cam.ExposureTime.GetMax() exposure_time_to_set = min(max_exposure, exposure_time_to_set) cam.AcquisitionFrameRateEnable.SetValue(True) cam.ExposureTime.SetValue(exposure_time_to_set) cam.AcquisitionFrameRate.SetValue(record_frame_rate) exposure_time_to_set = cam.ExposureTime.GetValue() record_frame_rate = cam.AcquisitionFrameRate.GetValue() max_exposure = cam.ExposureTime.GetMax() self.camq_p2read.put(exposure_time_to_set) self.camq_p2read.put(record_frame_rate) self.camq_p2read.put(max_exposure) elif msg == 'restoreXYWH': nodemap = cam.GetNodeMap() cam.BinningHorizontal.SetValue(int(1)) cam.BinningVertical.SetValue(int(1)) node_acquisition_mode = PySpin.CEnumerationPtr( nodemap.GetNode('AcquisitionMode')) if not PySpin.IsAvailable(node_acquisition_mode ) or not PySpin.IsWritable( node_acquisition_mode): print( 'Unable to set acquisition mode to continuous (enum retrieval). Aborting...' ) return False # Retrieve entry node from enumeration node node_acquisition_mode_continuous = node_acquisition_mode.GetEntryByName( 'Continuous') if not PySpin.IsAvailable( node_acquisition_mode_continuous ) or not PySpin.IsReadable( node_acquisition_mode_continuous): print( 'Unable to set acquisition mode to continuous (entry retrieval). Aborting...' ) return False acquisition_mode_continuous = node_acquisition_mode_continuous.GetValue( ) # Set integer value from entry node as new value of enumeration node node_acquisition_mode.SetIntValue( acquisition_mode_continuous) # Retrieve the enumeration node from the nodemap node_pixel_format = PySpin.CEnumerationPtr( nodemap.GetNode('PixelFormat')) if PySpin.IsAvailable( node_pixel_format) and PySpin.IsWritable( node_pixel_format): # Retrieve the desired entry node from the enumeration node node_pixel_format_mono8 = PySpin.CEnumEntryPtr( node_pixel_format.GetEntryByName('Mono8')) if PySpin.IsAvailable(node_pixel_format_mono8 ) and PySpin.IsReadable( node_pixel_format_mono8): # Retrieve the integer value from the entry node pixel_format_mono8 = node_pixel_format_mono8.GetValue( ) # Set integer as new value for enumeration node node_pixel_format.SetIntValue( pixel_format_mono8) else: print('Pixel format mono 8 not available...') else: print('Pixel format not available...') # Apply minimum to offset X node_offset_x = PySpin.CIntegerPtr( nodemap.GetNode('OffsetX')) if PySpin.IsAvailable( node_offset_x) and PySpin.IsWritable( node_offset_x): node_offset_x.SetValue(node_offset_x.GetMin()) else: print('Offset X not available...') # Apply minimum to offset Y node_offset_y = PySpin.CIntegerPtr( nodemap.GetNode('OffsetY')) if PySpin.IsAvailable( node_offset_y) and PySpin.IsWritable( node_offset_y): node_offset_y.SetValue(node_offset_y.GetMin()) else: print('Offset Y not available...') # Set maximum width node_width = PySpin.CIntegerPtr( nodemap.GetNode('Width')) if PySpin.IsAvailable( node_width) and PySpin.IsWritable(node_width): width_to_set = node_width.GetMax() node_width.SetValue(width_to_set) else: print('Width not available...') # Set maximum height node_height = PySpin.CIntegerPtr( nodemap.GetNode('Height')) if PySpin.IsAvailable( node_height) and PySpin.IsWritable( node_height): height_to_set = node_height.GetMax() node_height.SetValue(height_to_set) else: print('Height not available...') except PySpin.SpinnakerException as ex: print('Error: %s' % ex) print(self.camID) except Empty: pass