def start_scan(self): self._logger.info("Scan started") self._stop_scan = False self.hardwareController.laser.off() self.hardwareController.turntable.stop_turning() self.hardwareController.turntable.enable_motors() self.hardwareController.camera.device.startStream() self._resolution = int(self.settings.resolution) self._laser_positions = int(self.settings.laser_positions) self._is_color_scan = bool(self.settings.color) self._number_of_pictures = 3200 / int(self.settings.resolution) self.current_position = 0 #TODO: rename prefix to scan_id self._prefix = datetime.datetime.fromtimestamp( time.time()).strftime('%Y%m%d-%H%M%S') self.point_cloud = FSPointCloud(self._is_color_scan) self.image_processor = ImageProcessor(self.config, self.settings) if self._is_color_scan: self._total = self._number_of_pictures * 2 self.actor_ref.tell( {FSEvents.COMMAND: 'SCAN_NEXT_TEXTURE_POSITION'}) else: self._total = self._number_of_pictures self.actor_ref.tell( {FSEvents.COMMAND: 'SCAN_NEXT_OBJECT_POSITION'})
def __init__(self): super(FSSettingsPreviewProcessor, self).__init__() self.hardwareController = HardwareController.instance() self.eventManager = FSEventManager.instance() self.config = Config.instance() self.settings = Settings.instance() self._image_processor = ImageProcessor(self.config, self.settings)
def __init__(self, settings, config, image_task_q, event_q): super(FSImageWorkerProcess, self).__init__(group=None) self.image_task_q = image_task_q self.settings = settings self.config = config self.exit = False self.event_q = event_q self.log = logging.getLogger('IMAGE_PROCESSOR THREAD') self.log.setLevel(logging.DEBUG) self.image_processor = ImageProcessor(self.config, self.settings) self._logger = logging.getLogger(__name__) self._logger.setLevel(logging.DEBUG)
def start_scan(self): self._logger.info("Scan started") self._stop_scan = False self.hardwareController.laser.off() self.hardwareController.turntable.stop_turning() self.hardwareController.turntable.enable_motors() self.hardwareController.camera.device.startStream() self._resolution = int(self.settings.resolution) self._laser_positions = int(self.settings.laser_positions) self._is_color_scan = bool(self.settings.color) self._number_of_pictures = 3200 / int(self.settings.resolution) self.current_position = 0 #TODO: rename prefix to scan_id self._prefix = datetime.datetime.fromtimestamp(time.time()).strftime('%Y%m%d-%H%M%S') self.point_cloud = FSPointCloud(self._is_color_scan) self.image_processor = ImageProcessor(self.config,self.settings) if self._is_color_scan: self._total = self._number_of_pictures*2 self.actor_ref.tell({FSEvents.COMMAND:'SCAN_NEXT_TEXTURE_POSITION'}) else: self._total = self._number_of_pictures self.actor_ref.tell({FSEvents.COMMAND:'SCAN_NEXT_OBJECT_POSITION'})
class FSSettingsPreviewProcessor(pykka.ThreadingActor): def __init__(self): super(FSSettingsPreviewProcessor, self).__init__() self.hardwareController = HardwareController.instance() self.eventManager = FSEventManager.instance() self.config = Config.instance() self.settings = Settings.instance() self._image_processor = ImageProcessor(self.config, self.settings) def on_receive(self, event): if event['type'] == "CALIBRATION_STREAM": return self.create_calibration_stream() if event['type'] == "LASER_STREAM": return self.create_laser_stream() if event['type'] == "TEXTURE_STREAM": return self.create_texture_stream() def create_threshold_preview(self): return None def create_texture_stream(self): image = self.hardwareController.get_picture() image = self._image_processor.get_texture_stream_frame(image) return image def create_calibration_stream(self): image = self.hardwareController.get_picture() image = self._image_processor.get_calibration_stream_frame(image) return image def create_laser_stream(self): try: image = self.hardwareController.get_picture() image = self._image_processor.get_laser_stream_frame(image) return image except: ## catch image process error, e.g. when mjpeg stream is interupted pass
def __init__(self): self.config = Config.instance() self.settings = Settings.instance() self.camera = None self._image_processor = ImageProcessor(self.config, self.settings) self.camera = FSCamera() self.serial_connection = FSSerialCom() self.turntable = Turntable(self.serial_connection) self.laser = Laser(self.serial_connection) self.led = Led(self.serial_connection) self.laser.off() self.led.off() self.turntable.stop_turning() self.turntable.disable_motors()
class FSSettingsPreviewProcessor(pykka.ThreadingActor): def __init__(self): super(FSSettingsPreviewProcessor, self).__init__() self.hardwareController = HardwareController.instance() self.eventManager = FSEventManager.instance() self.config = Config.instance() self.settings = Settings.instance() self._image_processor = ImageProcessor(self.config, self.settings) def on_receive(self, event): if event['type'] == 'THRESHOLD': return self.create_threshold_preview() if event['type'] == 'CAMERA_PREVIEW': return self.create_camera_preview() if event['type'] == 'TEXTURE_PREVIEW': return self.create_texture_preview() def create_threshold_preview(self): return None def create_texture_preview(self): image = self.hardwareController.get_picture() image = self._image_processor.get_texture_preview_image(image) return image def create_camera_preview(self): try: image = self.hardwareController.get_picture() image = self._image_processor.get_preview_image(image) return image except: ## catch image process error, e.g. when mjpeg stream is interupted pass
def __init__(self, settings, config , image_task_q, event_q): super(FSImageWorkerProcess, self).__init__(group=None) self.image_task_q = image_task_q self.settings = settings self.config = config self.event_q = event_q self.log = logging.getLogger('IMAGE_PROCESSOR THREAD') self.log.setLevel(logging.DEBUG) self.image_processor = ImageProcessor(self.config, self.settings) self._logger = logging.getLogger(__name__) self._logger.setLevel(logging.DEBUG)
def __init__(self): self.config = Config.instance() self.settings = Settings.instance() self.camera = None self._image_processor = ImageProcessor(self.config, self.settings) self.camera = FSCamera() self.serial_connection = FSSerialCom() self.turntable = Turntable(self.serial_connection) self.laser = Laser(self.serial_connection) self.led = Led(self.serial_connection) self.laser.off() self.led.off() self.turntable.stop_turning()
class FSScanProcessor(pykka.ThreadingActor): def __init__(self): super(FSScanProcessor, self).__init__() self.eventManager = FSEventManager.instance() self.settings = Settings.instance() self.config = Config.instance() self._logger = logging.getLogger(__name__) self._logger.setLevel(logging.DEBUG) self._prefix = None self._resolution = 16 self._number_of_pictures = 0 self._total = 0 self._laser_positions = 1 self._progress = 0 self._is_color_scan = True self.point_cloud = None self.image_task_q = multiprocessing.Queue(self.config.process_numbers + 1) self.current_position = 0 self._laser_angle = 33.0 self._stop_scan = False self._current_laser_position = 1 self.semaphore = multiprocessing.BoundedSemaphore() self.event_q = self.eventManager.get_event_q() self._worker_pool = FSImageWorkerPool(self.image_task_q, self.event_q) self.hardwareController = HardwareController.instance() self.eventManager.subscribe(FSEvents.ON_IMAGE_PROCESSED, self.image_processed) self._scan_brightness = self.settings.camera.brightness self._scan_contrast = self.settings.camera.contrast self._scan_saturation = self.settings.camera.saturation def on_receive(self, event): if event[FSEvents.COMMAND] == FSScanProcessorCommand.START: self.start_scan() if event[FSEvents.COMMAND] == FSScanProcessorCommand.STOP: self.stop_scan() if event[FSEvents.COMMAND] == FSScanProcessorCommand.SETTINGS_MODE_ON: self.settings_mode_on() if event[FSEvents.COMMAND] == FSScanProcessorCommand.SETTINGS_MODE_OFF: self.settings_mode_off() if event[FSEvents.COMMAND] == FSScanProcessorCommand._SCAN_NEXT_TEXTURE_POSITION: self.scan_next_texture_position() if event[FSEvents.COMMAND] == FSScanProcessorCommand._SCAN_NEXT_OBJECT_POSITION: self.scan_next_object_position() if event[FSEvents.COMMAND] == FSScanProcessorCommand.NOTIFY_HARDWARE_STATE: self.send_hardware_state_notification() if event[FSEvents.COMMAND] == FSScanProcessorCommand.UPDATE_SETTINGS: self.update_settings(event['SETTINGS']) if event[FSEvents.COMMAND] == FSScanProcessorCommand.GET_HARDWARE_INFO: return self.hardwareController.get_firmware_version() def update_settings(self, settings): try: self.settings.update(settings) self.hardwareController.led.on(self.settings.led.red, self.settings.led.green, self.settings.led.blue) except: pass def send_hardware_state_notification(self): self._logger.debug("Checking Hardware connections") if not self.hardwareController.arduino_is_connected(): message = { "message": "NO_SERIAL_CONNECTION", "level": "error" } else: message = { "message": "SERIAL_CONNECTION_READY", "level": "info" } self.eventManager.broadcast_client_message(FSEvents.ON_INFO_MESSAGE, message) if not self.hardwareController.camera_is_connected(): message = { "message": "NO_CAMERA_CONNECTION", "level": "error" } else: message = { "message": "CAMERA_READY", "level": "info" } self.eventManager.broadcast_client_message(FSEvents.ON_INFO_MESSAGE, message) def settings_mode_on(self): self.hardwareController.settings_mode_on() def settings_mode_off(self): self.hardwareController.camera.device.stopStream() self.hardwareController.settings_mode_off() def start_scan(self): self.hardwareController.settings_mode_off() self._logger.info("Scan started") self._stop_scan = False self.hardwareController.laser.off() self.hardwareController.turntable.stop_turning() self.hardwareController.turntable.enable_motors() self.hardwareController.camera.device.startStream() self._resolution = int(self.settings.resolution) self._laser_positions = int(self.settings.laser_positions) self._is_color_scan = bool(self.settings.color) self._number_of_pictures = 3200 / int(self.settings.resolution) self.current_position = 0 # TODO: rename prefix to scan_id self._prefix = datetime.datetime.fromtimestamp(time.time()).strftime('%Y%m%d-%H%M%S') self.point_cloud = FSPointCloud(self._is_color_scan) self.image_processor = ImageProcessor(self.config, self.settings) if self._is_color_scan: self._total = self._number_of_pictures * 2 self.actor_ref.tell({FSEvents.COMMAND: FSScanProcessorCommand._SCAN_NEXT_TEXTURE_POSITION}) else: self._total = self._number_of_pictures self.actor_ref.tell({FSEvents.COMMAND: FSScanProcessorCommand._SCAN_NEXT_OBJECT_POSITION}) def init_texture_scan(self): message = { "message": "SCANNING_TEXTURE", "level": "info" } self.eventManager.broadcast_client_message(FSEvents.ON_INFO_MESSAGE, message) self._worker_pool.create(self.config.process_numbers) self._scan_brightness = self.settings.camera.brightness self._scan_contrast = self.settings.camera.contrast self._scan_saturation = self.settings.camera.saturation self.hardwareController.camera.device.textureExposure() self.settings.camera.brightness = 50 self.settings.camera.contrast = 0 self.settings.camera.saturation = 0 self.hardwareController.led.on(20, 20, 20) time.sleep(4) self.hardwareController.camera.device.flushStream() time.sleep(1) def finish_texture_scan(self): self._logger.info("Finishing texture scan.") self.current_position = 0 self.hardwareController.led.off() self.settings.camera.brightness = self._scan_brightness self.settings.camera.contrast = self._scan_contrast self.settings.camera.saturation = self._scan_saturation self._worker_pool.kill() def scan_next_texture_position(self): if not self._stop_scan: if self.current_position < self._number_of_pictures: if self.current_position == 0: self.init_texture_scan() color_image = self.hardwareController.scan_at_position(self._resolution, color=True) task = ImageTask(color_image, self._prefix, self.current_position, self._number_of_pictures, task_type="PROCESS_COLOR_IMAGE") self.image_task_q.put(task, True) self._logger.debug("Color Progress %i of %i : " % (self.current_position, self._number_of_pictures)) self.current_position += 1 self.actor_ref.tell({FSEvents.COMMAND: FSScanProcessorCommand._SCAN_NEXT_TEXTURE_POSITION}) else: self.finish_texture_scan() self.actor_ref.tell({FSEvents.COMMAND: FSScanProcessorCommand._SCAN_NEXT_OBJECT_POSITION}) def init_object_scan(self): self._logger.debug("Started object scan initialisation") self.current_position = 0 self._laser_positions = self.settings.laser_positions self.hardwareController.led.on(self.settings.led.red, self.settings.led.green, self.settings.led.blue) self.hardwareController.laser.on() self.settings.camera.brightness = self._scan_brightness self.settings.camera.contrast = self._scan_contrast self.settings.camera.saturation = self._scan_saturation # TODO: solve this timing issue! # Workaround for Logitech webcam. We have to wait a loooong time until the logitech cam is ready... # time.sleep(3) self.hardwareController.camera.device.objectExposure() self.hardwareController.camera.device.flushStream() time.sleep(2) self._laser_angle = self.image_processor.calculate_laser_angle(self.hardwareController.camera.device.getFrame()) if self._laser_angle == None: event = FSEvent() event.command = 'SCANNER_ERROR' self.eventManager.publish(FSEvents.COMMAND,event) self.on_laser_detection_failed() self._logger.debug("Send laser detection failure event") else: message = { "message": "SCANNING_OBJECT", "level": "info" } self.eventManager.broadcast_client_message(FSEvents.ON_INFO_MESSAGE, message) self._logger.debug("Detected Laser Angle at: %f deg" % (self._laser_angle,)) self._worker_pool.create(self.config.process_numbers) def finish_object_scan(self): self._logger.info("Finishing object scan.") self._worker_pool.kill() self.hardwareController.laser.off() self.hardwareController.led.off() self.hardwareController.camera.device.setPreviewResolution() def scan_next_object_position(self): if not self._stop_scan: if self.current_position < self._number_of_pictures: if self.current_position == 0: self.init_object_scan() laser_image = self.hardwareController.scan_at_position(self._resolution) task = ImageTask(laser_image, self._prefix, self.current_position, self._number_of_pictures) self.image_task_q.put(task) self._logger.debug("Laser Progress: %i of %i at laser position %i" % ( self.current_position, self._number_of_pictures, self._current_laser_position)) self.current_position += 1 self.actor_ref.tell({FSEvents.COMMAND: FSScanProcessorCommand._SCAN_NEXT_OBJECT_POSITION}) else: self.finish_object_scan() def on_laser_detection_failed(self): self._logger.info("Send laser detection failed message to frontend") message = { "message": "NO_LASER_FOUND", "level": "warn" } self.eventManager.broadcast_client_message(FSEvents.ON_INFO_MESSAGE, message) self.settings_mode_on() def stop_scan(self): self._stop_scan = True self._worker_pool.kill() time.sleep(1) FSUtil.delete_scan(self._prefix) self.reset_scanner_state() self._logger.info("Scan stoped") self.hardwareController.camera.device.stopStream() message = { "message": "SCAN_CANCELED", "level": "info" } self.eventManager.broadcast_client_message(FSEvents.ON_INFO_MESSAGE, message) def image_processed(self, eventManager, event): if event['image_type'] == 'laser': self.append_points(event['points']) self.semaphore.acquire() self._progress += 1 self.semaphore.release() message = { "points": event['points'], "progress": self._progress, "resolution": self._total } if self._progress == self._total: self.scan_complete() self.eventManager.broadcast_client_message(FSEvents.ON_NEW_PROGRESS, message) def scan_complete(self): self._logger.debug("Scan complete writing pointcloud files with %i points." % (self.point_cloud.get_size(),)) self.point_cloud.saveAsFile(self._prefix) self.settings.saveAsFile(self._prefix) message = { "message": "SAVING_POINT_CLOUD", "scan_id": self._prefix, "level": "info" } self.eventManager.broadcast_client_message(FSEvents.ON_INFO_MESSAGE, message) FSUtil.delete_image_folders(self._prefix) self.reset_scanner_state() event = FSEvent() event.command = 'COMPLETE' self.eventManager.publish(FSEvents.COMMAND,event) message = { "message": "SCAN_COMPLETE", "scan_id": self._prefix, "level": "success" } self.eventManager.broadcast_client_message(FSEvents.ON_INFO_MESSAGE, message) self.hardwareController.camera.device.stopStream() def append_points(self, point_set): if self.point_cloud: for point in point_set: self.point_cloud.append_point(point) def get_resolution(self): return self.settings.resolution def get_number_of_pictures(self): return self._number_of_pictures def get_folder_name(self): return self._prefix def reset_scanner_state(self): self._logger.info("Reseting scanner states ... ") self.hardwareController.camera.device.objectExposure() self.hardwareController.camera.device.flushStream() self.hardwareController.laser.off() self.hardwareController.led.off() self.hardwareController.turntable.disable_motors() self._command = None self._progress = 0 self.current_position = 0 self._number_of_pictures = 0 self._total = 0
class FSImageWorkerProcess(multiprocessing.Process): def __init__(self, settings, config , image_task_q, event_q): super(FSImageWorkerProcess, self).__init__(group=None) self.image_task_q = image_task_q self.settings = settings self.config = config self.event_q = event_q self.log = logging.getLogger('IMAGE_PROCESSOR THREAD') self.log.setLevel(logging.DEBUG) self.image_processor = ImageProcessor(self.config, self.settings) self._logger = logging.getLogger(__name__) self._logger.setLevel(logging.DEBUG) def run(self): ''' Image Process runner ''' #print "process "+str(self.pid)+" started" while True: if not self.image_task_q.empty(): #print "process "+str(self.pid)+" handle image" data = dict() try: image_task = self.image_task_q.get_nowait() if image_task: # we got a kill pill if image_task.task_type == "KILL": self._logger.debug("Killed Worker Process with PID "+str(self.pid)) break #print "process "+str(self.pid)+" task "+str(image_task.progress) if (image_task.task_type == "PROCESS_COLOR_IMAGE"): save_image(image_task.image, image_task.progress, image_task.prefix, dir_name=image_task.prefix+'/color_'+image_task.raw_dir) data['points'] = [] data['image_type'] = 'color' event = dict() event['event'] = "ON_IMAGE_PROCESSED" event['data'] = data self.event_q.put(event) if (image_task.task_type == "PROCESS_LASER_IMAGE"): angle = (image_task.progress) * 360 / image_task.resolution save_image(image_task.image, image_task.progress, image_task.prefix, dir_name=image_task.prefix+'/laser_'+image_task.raw_dir) color_image = load_image(image_task.progress, image_task.prefix, dir_name=image_task.prefix+'/color_'+image_task.raw_dir) points = self.image_processor.process_image(angle, image_task.image, color_image) data['points'] = points data['image_type'] = 'laser' #data['progress'] = image_task.progress #data['resolution'] = image_task.resolution event = dict() event['event'] = "ON_IMAGE_PROCESSED" event['data'] = data self.event_q.put(event) except Empty: pass else: # thread idle time.sleep(0.05)
class FSScanProcessor(pykka.ThreadingActor): def __init__(self): super(FSScanProcessor, self).__init__() self._logger = logging.getLogger(__name__) self._logger.setLevel(logging.DEBUG) self._prefix = None self._resolution = 16 self._number_of_pictures = 0 self._total = 0 self._laser_positions = 1 self._progress = 0 self._is_color_scan = True self.point_cloud = None self.image_task_q = multiprocessing.Queue(5) self.current_position = 0 self._laser_angle = 33.0 self._stop_scan = False self._current_laser_position = 1 self.eventManager = FSEventManager.instance() self.settings = Settings.instance() self.config = Config.instance() self.semaphore = multiprocessing.BoundedSemaphore() self._contrast = 0.5 self._brightness = 0.5 self.event_q = self.eventManager.get_event_q() self._worker_pool = FSImageWorkerPool(self.image_task_q,self.event_q) self.hardwareController = HardwareController.instance() self.eventManager.subscribe(FSEvents.ON_IMAGE_PROCESSED, self.image_processed) self._scan_brightness = self.settings.camera.brightness self._scan_contrast = self.settings.camera.contrast def on_receive(self, event): if event[FSEvents.COMMAND] == 'START': self.start_scan() if event[FSEvents.COMMAND] == 'STOP': self.stop_scan() if event[FSEvents.COMMAND] == 'SCAN_NEXT_TEXTURE_POSITION': self.scan_next_texture_position() if event[FSEvents.COMMAND] == 'SCAN_NEXT_OBJECT_POSITION': self.scan_next_object_position() def start_scan(self): self._stop_scan = False self.hardwareController.laser.off() self.hardwareController.turntable.stop_turning() self._resolution = int(self.settings.resolution) self._laser_positions = int(self.settings.laser_positions) self._is_color_scan = bool(self.settings.color) self._number_of_pictures = 3200 / int(self.settings.resolution) self.current_position = 0 #TODO: rename prefix to scan_id self._prefix = datetime.datetime.fromtimestamp(time.time()).strftime('%Y%m%d-%H%M%S') self.point_cloud = FSPointCloud(self._is_color_scan) self.image_processor = ImageProcessor(self.config,self.settings) if self._is_color_scan: self._total = self._number_of_pictures*2 self.actor_ref.tell({FSEvents.COMMAND:'SCAN_NEXT_TEXTURE_POSITION'}) else: self._total = self._number_of_pictures self.actor_ref.tell({FSEvents.COMMAND:'SCAN_NEXT_OBJECT_POSITION'}) def init_texture_scan(self): message = FSUtil.new_message() message['type'] = FSEvents.ON_INFO_MESSAGE message['data']['message'] = "SCANNING_TEXTURE" self.eventManager.publish(FSEvents.ON_SOCKET_BROADCAST,message) self._worker_pool.create(self.config.process_number) self._scan_brightness = self.settings.camera.brightness self._scan_contrast = self.settings.camera.contrast self.settings.camera.brightness = 50 self.settings.camera.contrast = 0 self.hardwareController.led.on(50,50,50) time.sleep(2) self.hardwareController.camera.device.flushStream() time.sleep(1) self.hardwareController.camera.device.getStream() def finish_texture_scan(self): self.current_position = 0 self.hardwareController.led.off() self.settings.camera.brightness = self._scan_brightness self.settings.camera.contrast = self._scan_contrast self._worker_pool.kill() def scan_next_texture_position(self): if not self._stop_scan: if self.current_position < self._number_of_pictures: if self.current_position == 0: self.init_texture_scan() color_image = self.hardwareController.scan_at_position(self._resolution, color=True) task = ImageTask(color_image, self._prefix, self.current_position, self._number_of_pictures, task_type="PROCESS_COLOR_IMAGE") self.image_task_q.put(task,True) self._logger.debug("Color Progress %i of %i : " % (self.current_position, self._number_of_pictures)) self.current_position +=1 self.actor_ref.tell({FSEvents.COMMAND:'SCAN_NEXT_TEXTURE_POSITION'}) else: self.finish_texture_scan() self.actor_ref.tell({FSEvents.COMMAND:'SCAN_NEXT_OBJECT_POSITION'}) def init_object_scan(self): message = FSUtil.new_message() message['type'] = FSEvents.ON_INFO_MESSAGE message['data']['message'] = "SCANNING_OBJECT" self.current_position = 0 self.eventManager.publish(FSEvents.ON_SOCKET_BROADCAST,message) self._laser_positions = self.settings.laser_positions self.hardwareController.led.on(self.settings.led.red,self.settings.led.green,self.settings.led.blue) self.hardwareController.laser.on() self.settings.camera.brightness = self._scan_brightness self.settings.camera.contrast = self._scan_contrast # TODO: solve this timing issue! # Workaround for Logitech webcam. We have to wait a loooong time until the logitech cam is ready... #time.sleep(3) self.hardwareController.camera.device.objectExposure() self._laser_angle = self.image_processor.calculate_laser_angle(self.hardwareController.camera.device.getStream()) self._logger.debug("Detected Laser Angle at: %f deg" %(self._laser_angle, )) self._worker_pool.create(self.config.process_number) def finish_object_scan(self): self._worker_pool.kill() self.hardwareController.laser.off() self.hardwareController.led.off() self.hardwareController.camera.device.setPreviewResolution() def scan_next_object_position(self): if not self._stop_scan: if self.current_position < self._number_of_pictures: if self.current_position == 0: self.init_object_scan() laser_image = self.hardwareController.scan_at_position(self._resolution) task = ImageTask(laser_image, self._prefix, self.current_position, self._number_of_pictures) self.image_task_q.put(task) self._logger.debug("Laser Progress: %i of %i at laser position %i" %(self.current_position, self._number_of_pictures , self._current_laser_position)) self.current_position +=1 self.actor_ref.tell({FSEvents.COMMAND:'SCAN_NEXT_OBJECT_POSITION'}) else: self.finish_object_scan() def stop_scan(self): self._stop_scan = True self._worker_pool.kill() time.sleep(1) FSUtil.delete_scan(self._prefix) self.reset_scanner_state() def on_stop(self): message = FSUtil.new_message() message['type'] = FSEvents.ON_INFO_MESSAGE message['data']['message'] = "SCAN_CANCELED" self.eventManager.publish(FSEvents.ON_SOCKET_BROADCAST,message) #self.eventManager.unsubscribe(FSEvents.ON_IMAGE_PROCESSED, self.image_processed) def image_processed(self, eventManager, event): if event['image_type'] == 'laser': self.append_points(event['points']) self.semaphore.acquire() self._progress +=1 self.semaphore.release() message = FSUtil.new_message() message['type'] = FSEvents.ON_NEW_PROGRESS message['data']['points'] = event['points'] message['data']['progress'] = self._progress message['data']['resolution'] = self._total if self._progress == self._total: self.scan_complete() eventManager.publish(FSEvents.ON_SOCKET_BROADCAST, message) def scan_complete(self): self._logger.debug("Scan complete writing pointcloud files with %i points." % (self.point_cloud.get_size(),)) self.point_cloud.saveAsFile(self._prefix) self.settings.saveAsFile(self._prefix) FSUtil.delete_image_folders(self._prefix) self.reset_scanner_state() event = FSEvent() event.command = '_COMPLETE' #TODO: generate MESH Here! self.eventManager.publish(FSEvents.COMMAND,event) message = FSUtil.new_message() message['type'] = FSEvents.ON_INFO_MESSAGE message['data']['message'] = "SCAN_COMPLETE" message['data']['scan_id'] = self._prefix self.eventManager.publish(FSEvents.ON_SOCKET_BROADCAST,message) def create_mesh(self, prefix): basedir = os.path.dirname(os.path.dirname(__file__)) input = self.config.folders.scans+str(prefix)+"/"+str(prefix)+".ply" output = self.config.folders.scans+str(prefix)+"/"+str(prefix)+".stl" mlx = basedir+"/fabscan/static/data/mlx/default_mesh.mlx" os.environ["DISPLAY"]=":0" subprocess.call([self.config.meshlab.path+"/meshlabserver -i "+input+" -o "+output+" -s "+mlx],shell=True) self._logger.debug("STL File written.") def append_points(self, point_set): if self.point_cloud: for point in point_set: self.point_cloud.append_point(point) def get_resolution(self): return self.settings.resolution def get_number_of_pictures(self): return self._number_of_pictures def get_folder_name(self): return self._prefix def reset_scanner_state(self): self.hardwareController.laser.off() self.hardwareController.led.off() self._command = None self._progress = 0 self.current_position = 0 self._number_of_pictures = 0 self._total = 0
class FSScanProcessor(pykka.ThreadingActor): def __init__(self): super(FSScanProcessor, self).__init__() self.eventManager = FSEventManager.instance() self.settings = Settings.instance() self.config = Config.instance() self._logger = logging.getLogger(__name__) self._logger.setLevel(logging.DEBUG) self._prefix = None self._resolution = 16 self._number_of_pictures = 0 self._total = 0 self._laser_positions = 1 self._progress = 0 self._is_color_scan = True self.point_cloud = None self.image_task_q = multiprocessing.Queue(self.config.process_numbers+1) self.current_position = 0 self._laser_angle = 33.0 self._stop_scan = False self._current_laser_position = 1 self.semaphore = multiprocessing.BoundedSemaphore() self.event_q = self.eventManager.get_event_q() self._worker_pool = FSImageWorkerPool(self.image_task_q,self.event_q) self.hardwareController = HardwareController.instance() self.eventManager.subscribe(FSEvents.ON_IMAGE_PROCESSED, self.image_processed) self._scan_brightness = self.settings.camera.brightness self._scan_contrast = self.settings.camera.contrast self._scan_saturation = self.settings.camera.saturation def on_receive(self, event): if event[FSEvents.COMMAND] == 'START': self.start_scan() if event[FSEvents.COMMAND] == 'STOP': self.stop_scan() if event[FSEvents.COMMAND] == 'SCAN_NEXT_TEXTURE_POSITION': self.scan_next_texture_position() if event[FSEvents.COMMAND] == 'SCAN_NEXT_OBJECT_POSITION': self.scan_next_object_position() def start_scan(self): self._logger.info("Scan started") self._stop_scan = False self.hardwareController.laser.off() self.hardwareController.turntable.stop_turning() self.hardwareController.turntable.enable_motors() self.hardwareController.camera.device.startStream() self._resolution = int(self.settings.resolution) self._laser_positions = int(self.settings.laser_positions) self._is_color_scan = bool(self.settings.color) self._number_of_pictures = 3200 / int(self.settings.resolution) self.current_position = 0 #TODO: rename prefix to scan_id self._prefix = datetime.datetime.fromtimestamp(time.time()).strftime('%Y%m%d-%H%M%S') self.point_cloud = FSPointCloud(self._is_color_scan) self.image_processor = ImageProcessor(self.config,self.settings) if self._is_color_scan: self._total = self._number_of_pictures*2 self.actor_ref.tell({FSEvents.COMMAND:'SCAN_NEXT_TEXTURE_POSITION'}) else: self._total = self._number_of_pictures self.actor_ref.tell({FSEvents.COMMAND:'SCAN_NEXT_OBJECT_POSITION'}) def init_texture_scan(self): message = FSUtil.new_message() message['type'] = FSEvents.ON_INFO_MESSAGE message['data']['message'] = "SCANNING_TEXTURE" message['data']['level'] = "info" self.eventManager.publish(FSEvents.ON_SOCKET_BROADCAST,message) self._worker_pool.create(self.config.process_numbers) self._scan_brightness = self.settings.camera.brightness self._scan_contrast = self.settings.camera.contrast self._scan_saturation = self.settings.camera.saturation self.hardwareController.camera.device.textureExposure() self.settings.camera.brightness = 50 self.settings.camera.contrast = 0 self.settings.camera.saturation = 0 self.hardwareController.led.on(60,60,60) time.sleep(2) self.hardwareController.camera.device.flushStream() time.sleep(1) def finish_texture_scan(self): self._logger.info("Finishing texture scan.") self.current_position = 0 self.hardwareController.led.off() self.settings.camera.brightness = self._scan_brightness self.settings.camera.contrast = self._scan_contrast self.settings.camera.saturation = self._scan_saturation self._worker_pool.kill() def scan_next_texture_position(self): if not self._stop_scan: if self.current_position < self._number_of_pictures: if self.current_position == 0: self.init_texture_scan() color_image = self.hardwareController.scan_at_position(self._resolution, color=True) task = ImageTask(color_image, self._prefix, self.current_position, self._number_of_pictures, task_type="PROCESS_COLOR_IMAGE") self.image_task_q.put(task,True) self._logger.debug("Color Progress %i of %i : " % (self.current_position, self._number_of_pictures)) self.current_position +=1 self.actor_ref.tell({FSEvents.COMMAND:'SCAN_NEXT_TEXTURE_POSITION'}) else: self.finish_texture_scan() self.actor_ref.tell({FSEvents.COMMAND:'SCAN_NEXT_OBJECT_POSITION'}) def init_object_scan(self): self._logger.debug("Started object scan initialisation") self.current_position = 0 self._laser_positions = self.settings.laser_positions self.hardwareController.led.on(self.settings.led.red,self.settings.led.green,self.settings.led.blue) self.hardwareController.laser.on() self.settings.camera.brightness = self._scan_brightness self.settings.camera.contrast = self._scan_contrast self.settings.camera.saturation = self._scan_saturation # TODO: solve this timing issue! # Workaround for Logitech webcam. We have to wait a loooong time until the logitech cam is ready... #time.sleep(3) self.hardwareController.camera.device.objectExposure() self.hardwareController.camera.device.flushStream() time.sleep(2) self._laser_angle = self.image_processor.calculate_laser_angle(self.hardwareController.camera.device.getFrame()) if self._laser_angle == None: event = FSEvent() event.command = '_LASER_DETECTION_FAILED' self.eventManager.publish(FSEvents.COMMAND,event) self.on_laser_detection_failed() self._logger.debug("Send laser detection failure event") else: message = FSUtil.new_message() message['type'] = FSEvents.ON_INFO_MESSAGE message['data']['message'] = "SCANNING_OBJECT" message['data']['level'] = "info" self.eventManager.publish(FSEvents.ON_SOCKET_BROADCAST,message) self._logger.debug("Detected Laser Angle at: %f deg" %(self._laser_angle, )) self._worker_pool.create(self.config.process_numbers) def finish_object_scan(self): self._logger.info("Finishing object scan.") self._worker_pool.kill() self.hardwareController.laser.off() self.hardwareController.led.off() self.hardwareController.camera.device.setPreviewResolution() def scan_next_object_position(self): if not self._stop_scan: if self.current_position < self._number_of_pictures: if self.current_position == 0: self.init_object_scan() laser_image = self.hardwareController.scan_at_position(self._resolution) task = ImageTask(laser_image, self._prefix, self.current_position, self._number_of_pictures) self.image_task_q.put(task) self._logger.debug("Laser Progress: %i of %i at laser position %i" %(self.current_position, self._number_of_pictures , self._current_laser_position)) self.current_position +=1 self.actor_ref.tell({FSEvents.COMMAND:'SCAN_NEXT_OBJECT_POSITION'}) else: self.finish_object_scan() def on_laser_detection_failed(self): self._logger.info("Send laser detection failed message to frontend") message = FSUtil.new_message() message['type'] = FSEvents.ON_INFO_MESSAGE message['data']['message'] = "NO_LASER_FOUND" message['data']['level'] = "warn" self.eventManager.publish(FSEvents.ON_SOCKET_BROADCAST,message) def stop_scan(self): self._stop_scan = True self._worker_pool.kill() time.sleep(1) FSUtil.delete_scan(self._prefix) self.reset_scanner_state() self._logger.info("Scan stoped") def on_stop(self): message = FSUtil.new_message() message['type'] = FSEvents.ON_INFO_MESSAGE message['data']['message'] = "SCAN_CANCELED" message['data']['level'] = "info" self.eventManager.publish(FSEvents.ON_SOCKET_BROADCAST,message) #self.eventManager.unsubscribe(FSEvents.ON_IMAGE_PROCESSED, self.image_processed) def image_processed(self, eventManager, event): if event['image_type'] == 'laser': self.append_points(event['points']) self.semaphore.acquire() self._progress +=1 self.semaphore.release() message = FSUtil.new_message() message['type'] = FSEvents.ON_NEW_PROGRESS message['data']['points'] = event['points'] message['data']['progress'] = self._progress message['data']['resolution'] = self._total if self._progress == self._total: self.scan_complete() eventManager.publish(FSEvents.ON_SOCKET_BROADCAST, message) def scan_complete(self): self._logger.debug("Scan complete writing pointcloud files with %i points." % (self.point_cloud.get_size(),)) self.point_cloud.saveAsFile(self._prefix) self.settings.saveAsFile(self._prefix) message = FSUtil.new_message() message['type'] = FSEvents.ON_INFO_MESSAGE message['data']['message'] = "SAVING_POINT_CLOUD" message['data']['scan_id'] = self._prefix message['data']['level'] = "info" self.eventManager.publish(FSEvents.ON_SOCKET_BROADCAST,message) FSUtil.delete_image_folders(self._prefix) self.reset_scanner_state() event = FSEvent() event.command = '_COMPLETE' #TODO: generate MESH Here if option is selected in scan settings! #self.create_mesh(self._prefix) self.eventManager.publish(FSEvents.COMMAND,event) message = FSUtil.new_message() message['type'] = FSEvents.ON_INFO_MESSAGE message['data']['message'] = "SCAN_COMPLETE" message['data']['scan_id'] = self._prefix message['data']['level'] = "success" self.eventManager.publish(FSEvents.ON_SOCKET_BROADCAST,message) def append_points(self, point_set): if self.point_cloud: for point in point_set: self.point_cloud.append_point(point) def get_resolution(self): return self.settings.resolution def get_number_of_pictures(self): return self._number_of_pictures def get_folder_name(self): return self._prefix def reset_scanner_state(self): self._logger.info("Reseting scanner states ... ") self.hardwareController.camera.device.objectExposure() self.hardwareController.camera.device.flushStream() self.hardwareController.laser.off() self.hardwareController.led.off() self.hardwareController.turntable.disable_motors() self._command = None self._progress = 0 self.current_position = 0 self._number_of_pictures = 0 self._total = 0
class HardwareController(SingletonMixin): """ Wrapper class for getting the Laser, Camera, and Turntable classes working together """ def __init__(self): self.config = Config.instance() self.settings = Settings.instance() self.camera = None self._image_processor = ImageProcessor(self.config, self.settings) self.camera = FSCamera() self.serial_connection = FSSerialCom() self.turntable = Turntable(self.serial_connection) self.laser = Laser(self.serial_connection) self.led = Led(self.serial_connection) self.laser.off() self.led.off() self.turntable.stop_turning() self.turntable.disable_motors() def settings_mode_on(self): self.laser.on() self.turntable.start_turning() self.camera.device.startStream() def settings_mode_off(self): self.turntable.stop_turning() self.led.off() self.laser.off() self.camera.device.flushStream() self.camera.device.stopStream() def get_picture(self): img = self.camera.device.getFrame() return img def scan_at_position(self, steps=180, color=False): ''' Take a step and return an image. Step size calculated to correspond to num_steps_per_rotation Returns resulting image ''' if color: speed = 800 else: speed = 50 self.turntable.step_interval(steps, speed) img = self.camera.device.getFrame() return img def get_laser_angle(self): image = self.camera.device.getFrame() angle = self._image_processor.calculate_laser_angle(image) return angle def arduino_is_connected(self): return self.serial_connection.is_connected() def get_firmware_version(self): return self.serial_connection.get_firmware_version() def camera_is_connected(self): return self.camera.is_connected() def calibrate_laser(self): self.laser.on() time.sleep(0.8) last_angle = 0 current_angle = self.get_laser_angle() #while (last_angle != current_angle): # last_angle = current_angle # current_angle = self.get_laser_angle() #angle_delta = 1 #while(not (angle_delta < 0.3 and angle_delta > -0.3)): # laser_angle = self.get_laser_angle() # angle_delta = 30 - laser_angle # if angle_delta > 0.3: # self.laser.turn(1) # elif angle_delta < -0.3: # self.laser.turn(-1) #delta_angle = 30 - first_detected_angle #steps = delta_angle/0.1125*3200 #self.laser.turn(int(360/steps)) #angle = self.get_laser_angle() self.laser.off() return current_angle
class FSScanProcessor(pykka.ThreadingActor): def __init__(self): super(FSScanProcessor, self).__init__() self.eventManager = FSEventManager.instance() self.settings = Settings.instance() self.config = Config.instance() self._logger = logging.getLogger(__name__) self._logger.setLevel(logging.DEBUG) self._prefix = None self._resolution = 16 self._number_of_pictures = 0 self._total = 0 self._laser_positions = 1 self._progress = 0 self._is_color_scan = True self.point_cloud = None self.image_task_q = multiprocessing.Queue(self.config.process_numbers + 1) self.current_position = 0 self._laser_angle = 33.0 self._stop_scan = False self._current_laser_position = 1 self.semaphore = multiprocessing.BoundedSemaphore() self.event_q = self.eventManager.get_event_q() self._worker_pool = FSImageWorkerPool(self.image_task_q, self.event_q) self.hardwareController = HardwareController.instance() self.eventManager.subscribe(FSEvents.ON_IMAGE_PROCESSED, self.image_processed) self._scan_brightness = self.settings.camera.brightness self._scan_contrast = self.settings.camera.contrast self._scan_saturation = self.settings.camera.saturation def on_receive(self, event): if event[FSEvents.COMMAND] == 'START': self.start_scan() if event[FSEvents.COMMAND] == 'STOP': self.stop_scan() if event[FSEvents.COMMAND] == 'SCAN_NEXT_TEXTURE_POSITION': self.scan_next_texture_position() if event[FSEvents.COMMAND] == 'SCAN_NEXT_OBJECT_POSITION': self.scan_next_object_position() def start_scan(self): self._logger.info("Scan started") self._stop_scan = False self.hardwareController.laser.off() self.hardwareController.turntable.stop_turning() self.hardwareController.turntable.enable_motors() self.hardwareController.camera.device.startStream() self._resolution = int(self.settings.resolution) self._laser_positions = int(self.settings.laser_positions) self._is_color_scan = bool(self.settings.color) self._number_of_pictures = 3200 / int(self.settings.resolution) self.current_position = 0 #TODO: rename prefix to scan_id self._prefix = datetime.datetime.fromtimestamp( time.time()).strftime('%Y%m%d-%H%M%S') self.point_cloud = FSPointCloud(self._is_color_scan) self.image_processor = ImageProcessor(self.config, self.settings) if self._is_color_scan: self._total = self._number_of_pictures * 2 self.actor_ref.tell( {FSEvents.COMMAND: 'SCAN_NEXT_TEXTURE_POSITION'}) else: self._total = self._number_of_pictures self.actor_ref.tell( {FSEvents.COMMAND: 'SCAN_NEXT_OBJECT_POSITION'}) def init_texture_scan(self): message = FSUtil.new_message() message['type'] = FSEvents.ON_INFO_MESSAGE message['data']['message'] = "SCANNING_TEXTURE" message['data']['level'] = "info" self.eventManager.publish(FSEvents.ON_SOCKET_BROADCAST, message) self._worker_pool.create(self.config.process_numbers) self._scan_brightness = self.settings.camera.brightness self._scan_contrast = self.settings.camera.contrast self._scan_saturation = self.settings.camera.saturation self.hardwareController.camera.device.textureExposure() self.settings.camera.brightness = 50 self.settings.camera.contrast = 0 self.settings.camera.saturation = 0 self.hardwareController.led.on(30, 30, 30) time.sleep(2) self.hardwareController.camera.device.flushStream() time.sleep(1) def finish_texture_scan(self): self._logger.info("Finishing texture scan.") self.current_position = 0 self.hardwareController.led.off() self.settings.camera.brightness = self._scan_brightness self.settings.camera.contrast = self._scan_contrast self.settings.camera.saturation = self._scan_saturation self._worker_pool.kill() def scan_next_texture_position(self): if not self._stop_scan: if self.current_position < self._number_of_pictures: if self.current_position == 0: self.init_texture_scan() color_image = self.hardwareController.scan_at_position( self._resolution, color=True) task = ImageTask(color_image, self._prefix, self.current_position, self._number_of_pictures, task_type="PROCESS_COLOR_IMAGE") self.image_task_q.put(task, True) self._logger.debug( "Color Progress %i of %i : " % (self.current_position, self._number_of_pictures)) self.current_position += 1 self.actor_ref.tell( {FSEvents.COMMAND: 'SCAN_NEXT_TEXTURE_POSITION'}) else: self.finish_texture_scan() self.actor_ref.tell( {FSEvents.COMMAND: 'SCAN_NEXT_OBJECT_POSITION'}) def init_object_scan(self): self._logger.debug("Started object scan initialisation") self.current_position = 0 self._laser_positions = self.settings.laser_positions self.hardwareController.led.on(self.settings.led.red, self.settings.led.green, self.settings.led.blue) self.hardwareController.laser.on() self.settings.camera.brightness = self._scan_brightness self.settings.camera.contrast = self._scan_contrast self.settings.camera.saturation = self._scan_saturation # TODO: solve this timing issue! # Workaround for Logitech webcam. We have to wait a loooong time until the logitech cam is ready... #time.sleep(3) self.hardwareController.camera.device.objectExposure() self.hardwareController.camera.device.flushStream() time.sleep(2) self._laser_angle = self.image_processor.calculate_laser_angle( self.hardwareController.camera.device.getFrame()) if self._laser_angle == None: event = FSEvent() event.command = '_LASER_DETECTION_FAILED' self.eventManager.publish(FSEvents.COMMAND, event) self.on_laser_detection_failed() self._logger.debug("Send laser detection failure event") else: message = FSUtil.new_message() message['type'] = FSEvents.ON_INFO_MESSAGE message['data']['message'] = "SCANNING_OBJECT" message['data']['level'] = "info" self.eventManager.publish(FSEvents.ON_SOCKET_BROADCAST, message) self._logger.debug("Detected Laser Angle at: %f deg" % (self._laser_angle, )) self._worker_pool.create(self.config.process_numbers) def finish_object_scan(self): self._logger.info("Finishing object scan.") self._worker_pool.kill() self.hardwareController.laser.off() self.hardwareController.led.off() self.hardwareController.camera.device.setPreviewResolution() def scan_next_object_position(self): if not self._stop_scan: if self.current_position < self._number_of_pictures: if self.current_position == 0: self.init_object_scan() laser_image = self.hardwareController.scan_at_position( self._resolution) task = ImageTask(laser_image, self._prefix, self.current_position, self._number_of_pictures) self.image_task_q.put(task) self._logger.debug( "Laser Progress: %i of %i at laser position %i" % (self.current_position, self._number_of_pictures, self._current_laser_position)) self.current_position += 1 self.actor_ref.tell( {FSEvents.COMMAND: 'SCAN_NEXT_OBJECT_POSITION'}) else: self.finish_object_scan() def on_laser_detection_failed(self): self._logger.info("Send laser detection failed message to frontend") message = FSUtil.new_message() message['type'] = FSEvents.ON_INFO_MESSAGE message['data']['message'] = "NO_LASER_FOUND" message['data']['level'] = "warn" self.eventManager.publish(FSEvents.ON_SOCKET_BROADCAST, message) def stop_scan(self): self._stop_scan = True self._worker_pool.kill() time.sleep(1) FSUtil.delete_scan(self._prefix) self.reset_scanner_state() self._logger.info("Scan stoped") def on_stop(self): message = FSUtil.new_message() message['type'] = FSEvents.ON_INFO_MESSAGE message['data']['message'] = "SCAN_CANCELED" message['data']['level'] = "info" self.eventManager.publish(FSEvents.ON_SOCKET_BROADCAST, message) #self.eventManager.unsubscribe(FSEvents.ON_IMAGE_PROCESSED, self.image_processed) def image_processed(self, eventManager, event): if event['image_type'] == 'laser': self.append_points(event['points']) self.semaphore.acquire() self._progress += 1 self.semaphore.release() message = FSUtil.new_message() message['type'] = FSEvents.ON_NEW_PROGRESS message['data']['points'] = event['points'] message['data']['progress'] = self._progress message['data']['resolution'] = self._total if self._progress == self._total: self.scan_complete() eventManager.publish(FSEvents.ON_SOCKET_BROADCAST, message) def scan_complete(self): self._logger.debug( "Scan complete writing pointcloud files with %i points." % (self.point_cloud.get_size(), )) self.point_cloud.saveAsFile(self._prefix) self.settings.saveAsFile(self._prefix) message = FSUtil.new_message() message['type'] = FSEvents.ON_INFO_MESSAGE message['data']['message'] = "SAVING_POINT_CLOUD" message['data']['scan_id'] = self._prefix message['data']['level'] = "info" self.eventManager.publish(FSEvents.ON_SOCKET_BROADCAST, message) FSUtil.delete_image_folders(self._prefix) self.reset_scanner_state() event = FSEvent() event.command = '_COMPLETE' #TODO: generate MESH Here if option is selected in scan settings! #self.create_mesh(self._prefix) self.eventManager.publish(FSEvents.COMMAND, event) message = FSUtil.new_message() message['type'] = FSEvents.ON_INFO_MESSAGE message['data']['message'] = "SCAN_COMPLETE" message['data']['scan_id'] = self._prefix message['data']['level'] = "success" self.eventManager.publish(FSEvents.ON_SOCKET_BROADCAST, message) def append_points(self, point_set): if self.point_cloud: for point in point_set: self.point_cloud.append_point(point) def get_resolution(self): return self.settings.resolution def get_number_of_pictures(self): return self._number_of_pictures def get_folder_name(self): return self._prefix def reset_scanner_state(self): self._logger.info("Reseting scanner states ... ") self.hardwareController.camera.device.objectExposure() self.hardwareController.camera.device.flushStream() self.hardwareController.laser.off() self.hardwareController.led.off() self.hardwareController.turntable.disable_motors() self._command = None self._progress = 0 self.current_position = 0 self._number_of_pictures = 0 self._total = 0
class FSImageWorkerProcess(multiprocessing.Process): def __init__(self, settings, config, image_task_q, event_q): super(FSImageWorkerProcess, self).__init__(group=None) self.image_task_q = image_task_q self.settings = settings self.config = config self.exit = False self.event_q = event_q self.log = logging.getLogger('IMAGE_PROCESSOR THREAD') self.log.setLevel(logging.DEBUG) self.image_processor = ImageProcessor(self.config, self.settings) self._logger = logging.getLogger(__name__) self._logger.setLevel(logging.DEBUG) def run(self): ''' Image Process runner ''' #print "process "+str(self.pid)+" started" while not self.exit: if not self.image_task_q.empty(): #print "process "+str(self.pid)+" handle image" data = dict() try: image_task = self.image_task_q.get_nowait() if image_task: # we got a kill pill if image_task.task_type == "KILL": self._logger.debug( "Killed Worker Process with PID " + str(self.pid)) self.exit = True break #print "process "+str(self.pid)+" task "+str(image_task.progress) if (image_task.task_type == "PROCESS_COLOR_IMAGE"): save_image(image_task.image, image_task.progress, image_task.prefix, dir_name=image_task.prefix + '/color_' + image_task.raw_dir) data['points'] = [] data['image_type'] = 'color' event = dict() event['event'] = "ON_IMAGE_PROCESSED" event['data'] = data self.event_q.put(event) if (image_task.task_type == "PROCESS_LASER_IMAGE"): angle = (image_task.progress ) * 360 / image_task.resolution save_image(image_task.image, image_task.progress, image_task.prefix, dir_name=image_task.prefix + '/laser_' + image_task.raw_dir) color_image = load_image( image_task.progress, image_task.prefix, dir_name=image_task.prefix + '/color_' + image_task.raw_dir) points = self.image_processor.process_image( angle, image_task.image, color_image) data['points'] = points data['image_type'] = 'laser' #data['progress'] = image_task.progress #data['resolution'] = image_task.resolution event = dict() event['event'] = "ON_IMAGE_PROCESSED" event['data'] = data self.event_q.put(event) except Empty: time.sleep(0.05) pass else: # thread idle time.sleep(0.05)