def get_frame(self): """Take a screenshot using ADB. If you are capturing video from the Android device via another method (HDMI or `Stb-tester CAMERA`_) sometimes it can be useful to capture a frame via ADB for debugging. This function will manipulate the ADB screenshot (scale and/or rotate it) to match the screenshots from your main video-capture method as closely as possible, as specified by the `CoordinateSystem`. :returns: A `stbt.Frame`, that is, an image in OpenCV format. Note that the ``time`` attribute won't be very accurate (probably to <0.5s or so). """ for attempt in range(1, 4): timestamp = time.time() data = (self.adb(["shell", "screencap", "-p"], timeout_secs=60, capture_output=True) .replace("\r\n", "\n")) img = cv2.imdecode( numpy.asarray(bytearray(data), dtype=numpy.uint8), cv2.CV_LOAD_IMAGE_COLOR) if img is None: logging.warning( "AdbDevice.get_frame: Failed to get screenshot " "via ADB (attempt %d/10)\n" "Length of data: %d", attempt, len(data)) else: break else: raise RuntimeError( "Failed to capture screenshot from android device") w, h = img.shape[1], img.shape[0] if self.coordinate_system == CoordinateSystem.ADB_NATIVE: pass elif self.coordinate_system == CoordinateSystem.ADB_720P: # Resize to 720p preserving orientation if w > h: img = cv2.resize(img, (1280, 720)) else: img = cv2.resize(img, (720, 1280)) elif self.coordinate_system == CoordinateSystem.CAMERA_720P: # Resize to 720p landscape for compatibility with screenshots from # `stbt.get_frame` with the Stb-tester CAMERA. if w > h: img = cv2.resize(img, (1280, 720)) else: img = numpy.rot90(cv2.resize(img, (720, 1280))) else: raise NotImplementedError( "AdbDevice.get_frame not implemented for %s. " "Use a separate AdbDevice instance with " "coordinate_system=CoordinateSystem.ADB_NATIVE" % self.coordinate_system) return stbt.Frame(img, time=timestamp)
def frames(self): if self._frames is not None: # Ignore self.state, send the specified frames instead. t = time.time() for state in self._frames: array = F(state, t) yield stbt.Frame(array, time=t) t += 0.04 # 25fps else: while True: t = time.time() array = F(self.state, t) if self.state == "fade-to-black": self.state = "black" elif self.state == "fade-to-white": self.state = "white" yield stbt.Frame(array, time=t)
def test_motionresult_repr(): assert repr(stbt.MotionResult( time=1466002032.335607, motion=True, region=stbt.Region(x=321, y=32, right=334, bottom=42), frame=stbt.Frame(numpy.zeros((720, 1280, 3)), time=1466002032.335607))) \ == ("MotionResult(" "time=1466002032.336, motion=True, " "region=Region(x=321, y=32, right=334, bottom=42), " "frame=<stbt.Frame(time=1466002032.336, dimensions=1280x720x3)>)")
def fake_frames(): a = numpy.zeros((2, 2, 3), dtype=numpy.uint8) a.flags.writeable = False b = numpy.ones((2, 2, 3), dtype=numpy.uint8) * 255 b.flags.writeable = False # Motion: v v v v v v v v v data = [a, a, a, a, a, a, b, b, a, a, b, b, a, a, b, b, a, a, b, b, a, a, b] # ^ ^ # | L Motion starts here at timestamp 1466084606. # L Video starts here at timestamp 1466084600 start_time = time.time() for n, x in enumerate(data): t = start_time + n time.sleep(t - time.time()) yield stbt.Frame(x, time=t)
def get_frame(self): """Take a screenshot using ADB. If you are capturing video from the Android device via another method (HDMI or `Stb-tester CAMERA`_) sometimes it can be useful to capture a frame via ADB for debugging. This function will manipulate the ADB screenshot (scale and/or rotate it) to match the screenshots from your main video-capture method as closely as possible, as specified by the `CoordinateSystem`. :returns: A `stbt.Frame`, that is, an image in OpenCV format. Note that the ``time`` attribute won't be very accurate (probably to <0.5s or so). """ import cv2 import numpy import stbt for attempt in range(1, 4): timestamp = time.time() data = (self.adb(["shell", "screencap", "-p"], timeout_secs=60, capture_output=True).replace("\r\n", "\n")) img = cv2.imdecode( numpy.asarray(bytearray(data), dtype=numpy.uint8), cv2.IMREAD_COLOR) if img is None: logging.warning( "AdbDevice.get_frame: Failed to get screenshot " "via ADB (attempt %d/3)\n" "Length of data: %d", attempt, len(data)) else: break else: raise RuntimeError( "Failed to capture screenshot from android device") img = _resize(img, self.coordinate_system) return stbt.Frame(img, time=timestamp)
def gradient_wipe(min_=100, max_=200, swipe_height=40): """Use write_video(gradient_wipe()) to see what this looks like.""" frame = min_ * numpy.ones( (720 + swipe_height * 4, 1280, 3), dtype=numpy.uint8) diff = max_ - min_ # detect_motion ignores differences of under 40, so what's the fastest we # can wipe while making sure the inter-frame differences are always under # 40?: speed = 40 * swipe_height / diff print("pixel difference: %f" % (diff / swipe_height)) print("max_speed: %f" % speed) edge = numpy.ones((swipe_height * 3, 1280, 3), dtype=numpy.uint8) * min_ for n in range(swipe_height * 3): edge[n, :, :] = clamp(max_ - (n - swipe_height) * diff / swipe_height, min_, max_) for x in range(0, frame.shape[0] - swipe_height * 3, int(speed)): frame[x:x + swipe_height * 3, :, :] = edge yield stbt.Frame(frame[swipe_height * 2:swipe_height * 2 + 720], time=x / 30.)
def fake_frames(): for i, f in enumerate( ["box-00001.png", "box-00002.png", "box-00003.png"]): yield stbt.Frame(stbt.load_image(f), time=i)
def wipe(): frame = numpy.zeros((720, 1280, 3), dtype=numpy.uint8) for x in range(0, 720, 2): frame[x:x + 2, :, :] = 255 yield stbt.Frame(frame, time=x / 30.)