コード例 #1
0
ファイル: input.py プロジェクト: napratin/lumos
 def __init__(self):
   # * Grab application context, logger and check if we have a valid input source
   self.context = Context.getInstance()
   self.logger = logging.getLogger(self.__class__.__name__)
   self.isOkay = False  # conservative assumption: not okay till we're ready
   if self.context.options.input_source is None:
     raise Exception("No valid input source, nothing to do!")
   
   # * Open input source
   if self.context.isImage:
     self.camera = cv2.imread(self.context.options.input_source)
     if self.camera is None:
       raise Exception("Error opening input image file")
   elif self.context.isRemote:
     from net import ImageClient  # to prevent circular dependency
     self.camera = ImageClient(protocol=self.context.remoteEndpoint['protocol'], host=self.context.remoteEndpoint['host'], port=self.context.remoteEndpoint['port'])
     # TODO Allow custom read_call param via command-line arg --rpc_read_call (or remoteEndpoint['path']?)
     # TODO Add ability to read remote URLs by (use a common isStatic flag for local and remote images)
   else:
     self.camera = cv2.VideoCapture(self.context.options.input_source)
     if self.camera is None or not self.camera.isOpened():
       raise Exception("Error opening camera / input video file")
   
   # * Acquire logger and initialize other members
   self.logger = logging.getLogger(self.__class__.__name__)
   self.frameCount = 0
   self.frameTimeStart = self.context.timeNow  # synced with context
   self.timeDelta = 0.0
   
   # * Set camera frame size (if this is a live camera; TODO enable frame resizing for videos and static images as well?)
   if not (self.context.isImage or self.context.isVideo or self.context.isRemote):
     #_, self.image = self.camera.read()  # pre-grab
     # NOTE: If camera frame size is not one supported by the hardware, grabbed images are scaled to desired size, discarding aspect-ratio
     try:
       if self.context.options.camera_width != 'auto':
         self.camera.set(cv.CV_CAP_PROP_FRAME_WIDTH, int(self.context.options.camera_width))
       if self.context.options.camera_height != 'auto':
         self.camera.set(cv.CV_CAP_PROP_FRAME_HEIGHT, int(self.context.options.camera_height))
     except ValueError:
       self.logger.warning("Ignoring invalid camera frame size: {}x{}".format(self.context.options.camera_width, self.context.options.camera_height))
   
   # * Check if this is a static image or camera/video/remote endpoint
   if self.context.isImage:
     # ** Supplied camera object should be an image, copy it
     self.image = self.camera
   else:
     if self.context.isVideo:
       # ** Read video properties, set video-specific variables
       self.videoNumFrames = int(self.camera.get(cv.CV_CAP_PROP_FRAME_COUNT))
       if self.context.options.video_fps == 'auto':
         self.videoFPS = self.camera.get(cv.CV_CAP_PROP_FPS)
       else:
         try:
           self.videoFPS = float(self.context.options.video_fps)
         except ValueError:
           self.logger.warning("Invalid video FPS \"{}\"; switching to auto".format(self.self.context.options.video_fps))
           self.videoFPS = self.camera.get(cv.CV_CAP_PROP_FPS)
       self.videoDuration = self.videoNumFrames / self.videoFPS
       self.logger.info("Video [init]: {:.3f} secs., {} frames at {:.2f} fps{}".format(self.videoDuration, self.videoNumFrames, self.videoFPS, (" (sync target)" if self.context.options.sync_video else "")))
       if self.context.options.sync_video:
         self.videoFramesRepeated = 0
         self.videoFramesSkipped = 0
     
     # ** Grab test image and read common camera/video properties
     self.readFrame()  # post-grab (to apply any camera prop changes made)
     if not self.context.isRemote:
       self.logger.info("Frame size: {}x{}".format(int(self.camera.get(cv.CV_CAP_PROP_FRAME_WIDTH)), int(self.camera.get(cv.CV_CAP_PROP_FRAME_HEIGHT))))
     if self.context.isVideo:
       self.resetVideo()
   
   # * Read image properties (common to static image/camera/video)
   if self.image is not None:
     self.imageSize = (self.image.shape[1], self.image.shape[0])
     self.logger.info("Image size: {}x{}".format(self.imageSize[0], self.imageSize[1]))
     self.isOkay = True  # all good, so far
   else:
     self.logger.error("Empty image!")
コード例 #2
0
ファイル: input.py プロジェクト: ziaridoy20/lumos
    def __init__(self):
        # * Grab application context, logger and check if we have a valid input source
        self.context = Context.getInstance()
        self.logger = logging.getLogger(self.__class__.__name__)
        self.isOkay = False  # conservative assumption: not okay till we're ready
        if self.context.options.input_source is None:
            raise Exception("No valid input source, nothing to do!")

        # * Open input source
        if self.context.isImage:
            self.camera = cv2.imread(self.context.options.input_source)
            if self.camera is None:
                raise Exception("Error opening input image file")
        elif self.context.isRemote:
            from net import ImageClient  # to prevent circular dependency
            self.camera = ImageClient(
                protocol=self.context.remoteEndpoint['protocol'],
                host=self.context.remoteEndpoint['host'],
                port=self.context.remoteEndpoint['port'])
            # TODO Allow custom read_call param via command-line arg --rpc_read_call (or remoteEndpoint['path']?)
            # TODO Add ability to read remote URLs by (use a common isStatic flag for local and remote images)
        else:
            self.camera = cv2.VideoCapture(self.context.options.input_source)
            if self.camera is None or not self.camera.isOpened():
                raise Exception("Error opening camera / input video file")

        # * Acquire logger and initialize other members
        self.logger = logging.getLogger(self.__class__.__name__)
        self.frameCount = 0
        self.frameTimeStart = self.context.timeNow  # synced with context
        self.timeDelta = 0.0

        # * Set camera frame size (if this is a live camera; TODO enable frame resizing for videos and static images as well?)
        if not (self.context.isImage or self.context.isVideo
                or self.context.isRemote):
            #_, self.image = self.camera.read()  # pre-grab
            # NOTE: If camera frame size is not one supported by the hardware, grabbed images are scaled to desired size, discarding aspect-ratio
            try:
                if self.context.options.camera_width != 'auto':
                    self.camera.set(cv.CV_CAP_PROP_FRAME_WIDTH,
                                    int(self.context.options.camera_width))
                if self.context.options.camera_height != 'auto':
                    self.camera.set(cv.CV_CAP_PROP_FRAME_HEIGHT,
                                    int(self.context.options.camera_height))
            except ValueError:
                self.logger.warning(
                    "Ignoring invalid camera frame size: {}x{}".format(
                        self.context.options.camera_width,
                        self.context.options.camera_height))

        # * Check if this is a static image or camera/video/remote endpoint
        if self.context.isImage:
            # ** Supplied camera object should be an image, copy it
            self.image = self.camera
        else:
            if self.context.isVideo:
                # ** Read video properties, set video-specific variables
                self.videoNumFrames = int(
                    self.camera.get(cv.CV_CAP_PROP_FRAME_COUNT))
                if self.context.options.video_fps == 'auto':
                    self.videoFPS = self.camera.get(cv.CV_CAP_PROP_FPS)
                else:
                    try:
                        self.videoFPS = float(self.context.options.video_fps)
                    except ValueError:
                        self.logger.warning(
                            "Invalid video FPS \"{}\"; switching to auto".
                            format(self.self.context.options.video_fps))
                        self.videoFPS = self.camera.get(cv.CV_CAP_PROP_FPS)
                self.videoDuration = self.videoNumFrames / self.videoFPS
                self.logger.info(
                    "Video [init]: {:.3f} secs., {} frames at {:.2f} fps{}".
                    format(self.videoDuration, self.videoNumFrames,
                           self.videoFPS,
                           (" (sync target)"
                            if self.context.options.sync_video else "")))
                if self.context.options.sync_video:
                    self.videoFramesRepeated = 0
                    self.videoFramesSkipped = 0

            # ** Grab test image and read common camera/video properties
            self.readFrame(
            )  # post-grab (to apply any camera prop changes made)
            if not self.context.isRemote:
                self.logger.info("Frame size: {}x{}".format(
                    int(self.camera.get(cv.CV_CAP_PROP_FRAME_WIDTH)),
                    int(self.camera.get(cv.CV_CAP_PROP_FRAME_HEIGHT))))
            if self.context.isVideo:
                self.resetVideo()

        # * Read image properties (common to static image/camera/video)
        if self.image is not None:
            self.imageSize = (self.image.shape[1], self.image.shape[0])
            self.logger.info("Image size: {}x{}".format(
                self.imageSize[0], self.imageSize[1]))
            self.isOkay = True  # all good, so far
        else:
            self.logger.error("Empty image!")
コード例 #3
0
ファイル: input.py プロジェクト: napratin/lumos
class InputDevice(object):
  """Abstracts away the handling of static image, recorded video files and live camera as input."""
  
  def __init__(self):
    # * Grab application context, logger and check if we have a valid input source
    self.context = Context.getInstance()
    self.logger = logging.getLogger(self.__class__.__name__)
    self.isOkay = False  # conservative assumption: not okay till we're ready
    if self.context.options.input_source is None:
      raise Exception("No valid input source, nothing to do!")
    
    # * Open input source
    if self.context.isImage:
      self.camera = cv2.imread(self.context.options.input_source)
      if self.camera is None:
        raise Exception("Error opening input image file")
    elif self.context.isRemote:
      from net import ImageClient  # to prevent circular dependency
      self.camera = ImageClient(protocol=self.context.remoteEndpoint['protocol'], host=self.context.remoteEndpoint['host'], port=self.context.remoteEndpoint['port'])
      # TODO Allow custom read_call param via command-line arg --rpc_read_call (or remoteEndpoint['path']?)
      # TODO Add ability to read remote URLs by (use a common isStatic flag for local and remote images)
    else:
      self.camera = cv2.VideoCapture(self.context.options.input_source)
      if self.camera is None or not self.camera.isOpened():
        raise Exception("Error opening camera / input video file")
    
    # * Acquire logger and initialize other members
    self.logger = logging.getLogger(self.__class__.__name__)
    self.frameCount = 0
    self.frameTimeStart = self.context.timeNow  # synced with context
    self.timeDelta = 0.0
    
    # * Set camera frame size (if this is a live camera; TODO enable frame resizing for videos and static images as well?)
    if not (self.context.isImage or self.context.isVideo or self.context.isRemote):
      #_, self.image = self.camera.read()  # pre-grab
      # NOTE: If camera frame size is not one supported by the hardware, grabbed images are scaled to desired size, discarding aspect-ratio
      try:
        if self.context.options.camera_width != 'auto':
          self.camera.set(cv.CV_CAP_PROP_FRAME_WIDTH, int(self.context.options.camera_width))
        if self.context.options.camera_height != 'auto':
          self.camera.set(cv.CV_CAP_PROP_FRAME_HEIGHT, int(self.context.options.camera_height))
      except ValueError:
        self.logger.warning("Ignoring invalid camera frame size: {}x{}".format(self.context.options.camera_width, self.context.options.camera_height))
    
    # * Check if this is a static image or camera/video/remote endpoint
    if self.context.isImage:
      # ** Supplied camera object should be an image, copy it
      self.image = self.camera
    else:
      if self.context.isVideo:
        # ** Read video properties, set video-specific variables
        self.videoNumFrames = int(self.camera.get(cv.CV_CAP_PROP_FRAME_COUNT))
        if self.context.options.video_fps == 'auto':
          self.videoFPS = self.camera.get(cv.CV_CAP_PROP_FPS)
        else:
          try:
            self.videoFPS = float(self.context.options.video_fps)
          except ValueError:
            self.logger.warning("Invalid video FPS \"{}\"; switching to auto".format(self.self.context.options.video_fps))
            self.videoFPS = self.camera.get(cv.CV_CAP_PROP_FPS)
        self.videoDuration = self.videoNumFrames / self.videoFPS
        self.logger.info("Video [init]: {:.3f} secs., {} frames at {:.2f} fps{}".format(self.videoDuration, self.videoNumFrames, self.videoFPS, (" (sync target)" if self.context.options.sync_video else "")))
        if self.context.options.sync_video:
          self.videoFramesRepeated = 0
          self.videoFramesSkipped = 0
      
      # ** Grab test image and read common camera/video properties
      self.readFrame()  # post-grab (to apply any camera prop changes made)
      if not self.context.isRemote:
        self.logger.info("Frame size: {}x{}".format(int(self.camera.get(cv.CV_CAP_PROP_FRAME_WIDTH)), int(self.camera.get(cv.CV_CAP_PROP_FRAME_HEIGHT))))
      if self.context.isVideo:
        self.resetVideo()
    
    # * Read image properties (common to static image/camera/video)
    if self.image is not None:
      self.imageSize = (self.image.shape[1], self.image.shape[0])
      self.logger.info("Image size: {}x{}".format(self.imageSize[0], self.imageSize[1]))
      self.isOkay = True  # all good, so far
    else:
      self.logger.error("Empty image!")
  
  def readFrame(self):
    """Read a frame from camera/video. Not meant to be called directly."""
    if self.context.isVideo and self.context.options.loop_video and self.frameCount >= self.videoNumFrames:
      framesDelivered = self.frameCount + self.videoFramesRepeated - self.videoFramesSkipped if self.context.options.sync_video else self.frameCount
      self.logger.info("Video [loop]: {:.3f} secs., {} frames at {:.2f} fps{}".format(
        self.timeDelta,
        framesDelivered,
        (framesDelivered / self.timeDelta) if self.timeDelta > 0.0 else 0.0,
        (" ({} repeated, {} skipped)".format(self.videoFramesRepeated, self.videoFramesSkipped) if self.context.options.sync_video else "")))
      self.resetVideo()
      if self.context.options.sync_video:
        self.videoFramesRepeated = 0
        self.videoFramesSkipped = 0
    
    self.isOkay, self.image = self.camera.read()
    self.frameCount += 1
  
  def read(self):
    """Read a frame from image/camera/video, handling video sync and loop."""
    self.timeDelta = self.context.timeNow - self.frameTimeStart  # synced with context
    
    if not self.context.isImage:
      if self.context.isVideo and self.context.options.sync_video:
        targetFrameCount = self.videoFPS * self.timeDelta
        diffFrameCount = targetFrameCount - self.frameCount
        #self.logger.debug("[syncVideo] timeDelta: {:06.3f}, frame: {:03d}, target: {:06.2f}, diff: {:+04.2f}".format(self.timeDelta, self.frameCount, targetFrameCount, diffFrameCount))
        if diffFrameCount <= 0:
          self.videoFramesRepeated += 1
        else:
          self.videoFramesSkipped += min(int(diffFrameCount), self.videoNumFrames - self.frameCount)
          while self.isOkay and self.frameCount < targetFrameCount:
            self.readFrame()
            if self.frameCount == 1:  # a video reset occurred
              break
      else:
        self.readFrame()
    
    return self.isOkay
  
  def resetVideo(self):
    self.camera.set(cv.CV_CAP_PROP_POS_FRAMES, 0)
    self.frameCount = 0
    self.frameTimeStart = self.context.timeNow  # synced with context
    self.timeDelta = 0.0
    # NOTE Depending on the actual keyframes in the video, a reset may not work correctly (some frames towards the end may be skipped everytime after the first reset)
  
  def close(self):
    if not self.context.isImage:  # not valid for static images
      self.camera.release()
コード例 #4
0
ファイル: input.py プロジェクト: ziaridoy20/lumos
class InputDevice(object):
    """Abstracts away the handling of static image, recorded video files and live camera as input."""
    def __init__(self):
        # * Grab application context, logger and check if we have a valid input source
        self.context = Context.getInstance()
        self.logger = logging.getLogger(self.__class__.__name__)
        self.isOkay = False  # conservative assumption: not okay till we're ready
        if self.context.options.input_source is None:
            raise Exception("No valid input source, nothing to do!")

        # * Open input source
        if self.context.isImage:
            self.camera = cv2.imread(self.context.options.input_source)
            if self.camera is None:
                raise Exception("Error opening input image file")
        elif self.context.isRemote:
            from net import ImageClient  # to prevent circular dependency
            self.camera = ImageClient(
                protocol=self.context.remoteEndpoint['protocol'],
                host=self.context.remoteEndpoint['host'],
                port=self.context.remoteEndpoint['port'])
            # TODO Allow custom read_call param via command-line arg --rpc_read_call (or remoteEndpoint['path']?)
            # TODO Add ability to read remote URLs by (use a common isStatic flag for local and remote images)
        else:
            self.camera = cv2.VideoCapture(self.context.options.input_source)
            if self.camera is None or not self.camera.isOpened():
                raise Exception("Error opening camera / input video file")

        # * Acquire logger and initialize other members
        self.logger = logging.getLogger(self.__class__.__name__)
        self.frameCount = 0
        self.frameTimeStart = self.context.timeNow  # synced with context
        self.timeDelta = 0.0

        # * Set camera frame size (if this is a live camera; TODO enable frame resizing for videos and static images as well?)
        if not (self.context.isImage or self.context.isVideo
                or self.context.isRemote):
            #_, self.image = self.camera.read()  # pre-grab
            # NOTE: If camera frame size is not one supported by the hardware, grabbed images are scaled to desired size, discarding aspect-ratio
            try:
                if self.context.options.camera_width != 'auto':
                    self.camera.set(cv.CV_CAP_PROP_FRAME_WIDTH,
                                    int(self.context.options.camera_width))
                if self.context.options.camera_height != 'auto':
                    self.camera.set(cv.CV_CAP_PROP_FRAME_HEIGHT,
                                    int(self.context.options.camera_height))
            except ValueError:
                self.logger.warning(
                    "Ignoring invalid camera frame size: {}x{}".format(
                        self.context.options.camera_width,
                        self.context.options.camera_height))

        # * Check if this is a static image or camera/video/remote endpoint
        if self.context.isImage:
            # ** Supplied camera object should be an image, copy it
            self.image = self.camera
        else:
            if self.context.isVideo:
                # ** Read video properties, set video-specific variables
                self.videoNumFrames = int(
                    self.camera.get(cv.CV_CAP_PROP_FRAME_COUNT))
                if self.context.options.video_fps == 'auto':
                    self.videoFPS = self.camera.get(cv.CV_CAP_PROP_FPS)
                else:
                    try:
                        self.videoFPS = float(self.context.options.video_fps)
                    except ValueError:
                        self.logger.warning(
                            "Invalid video FPS \"{}\"; switching to auto".
                            format(self.self.context.options.video_fps))
                        self.videoFPS = self.camera.get(cv.CV_CAP_PROP_FPS)
                self.videoDuration = self.videoNumFrames / self.videoFPS
                self.logger.info(
                    "Video [init]: {:.3f} secs., {} frames at {:.2f} fps{}".
                    format(self.videoDuration, self.videoNumFrames,
                           self.videoFPS,
                           (" (sync target)"
                            if self.context.options.sync_video else "")))
                if self.context.options.sync_video:
                    self.videoFramesRepeated = 0
                    self.videoFramesSkipped = 0

            # ** Grab test image and read common camera/video properties
            self.readFrame(
            )  # post-grab (to apply any camera prop changes made)
            if not self.context.isRemote:
                self.logger.info("Frame size: {}x{}".format(
                    int(self.camera.get(cv.CV_CAP_PROP_FRAME_WIDTH)),
                    int(self.camera.get(cv.CV_CAP_PROP_FRAME_HEIGHT))))
            if self.context.isVideo:
                self.resetVideo()

        # * Read image properties (common to static image/camera/video)
        if self.image is not None:
            self.imageSize = (self.image.shape[1], self.image.shape[0])
            self.logger.info("Image size: {}x{}".format(
                self.imageSize[0], self.imageSize[1]))
            self.isOkay = True  # all good, so far
        else:
            self.logger.error("Empty image!")

    def readFrame(self):
        """Read a frame from camera/video. Not meant to be called directly."""
        if self.context.isVideo and self.context.options.loop_video and self.frameCount >= self.videoNumFrames:
            framesDelivered = self.frameCount + self.videoFramesRepeated - self.videoFramesSkipped if self.context.options.sync_video else self.frameCount
            self.logger.info(
                "Video [loop]: {:.3f} secs., {} frames at {:.2f} fps{}".format(
                    self.timeDelta, framesDelivered,
                    (framesDelivered /
                     self.timeDelta) if self.timeDelta > 0.0 else 0.0,
                    (" ({} repeated, {} skipped)".format(
                        self.videoFramesRepeated, self.videoFramesSkipped)
                     if self.context.options.sync_video else "")))
            self.resetVideo()
            if self.context.options.sync_video:
                self.videoFramesRepeated = 0
                self.videoFramesSkipped = 0

        self.isOkay, self.image = self.camera.read()
        self.frameCount += 1

    def read(self):
        """Read a frame from image/camera/video, handling video sync and loop."""
        self.timeDelta = self.context.timeNow - self.frameTimeStart  # synced with context

        if not self.context.isImage:
            if self.context.isVideo and self.context.options.sync_video:
                targetFrameCount = self.videoFPS * self.timeDelta
                diffFrameCount = targetFrameCount - self.frameCount
                #self.logger.debug("[syncVideo] timeDelta: {:06.3f}, frame: {:03d}, target: {:06.2f}, diff: {:+04.2f}".format(self.timeDelta, self.frameCount, targetFrameCount, diffFrameCount))
                if diffFrameCount <= 0:
                    self.videoFramesRepeated += 1
                else:
                    self.videoFramesSkipped += min(
                        int(diffFrameCount),
                        self.videoNumFrames - self.frameCount)
                    while self.isOkay and self.frameCount < targetFrameCount:
                        self.readFrame()
                        if self.frameCount == 1:  # a video reset occurred
                            break
            else:
                self.readFrame()

        return self.isOkay

    def resetVideo(self):
        self.camera.set(cv.CV_CAP_PROP_POS_FRAMES, 0)
        self.frameCount = 0
        self.frameTimeStart = self.context.timeNow  # synced with context
        self.timeDelta = 0.0
        # NOTE Depending on the actual keyframes in the video, a reset may not work correctly (some frames towards the end may be skipped everytime after the first reset)

    def close(self):
        if not self.context.isImage:  # not valid for static images
            self.camera.release()