diff --git a/tools/pyopenmv.py b/tools/pyopenmv.py index 8bf1034b3..c43d38bfa 100755 --- a/tools/pyopenmv.py +++ b/tools/pyopenmv.py @@ -84,7 +84,7 @@ def read_state(): text = text_buf.split(b'\0', 1)[0].decode() if flags & __USBDBG_STATE_FLAGS_FRAME == 0: - return 0, 0, None, text + return 0, 0, None, 0, text num_bytes = size if size > 2 else (w * h * size) @@ -95,12 +95,14 @@ def read_state(): if size == 1: # Grayscale y = np.fromstring(buff, dtype=np.uint8) buff = np.column_stack((y, y, y)) + size = w * h elif size == 2: # RGB565 arr = np.fromstring(buff, dtype=np.uint16).newbyteorder('S') r = (((arr & 0xF800) >>11)*255.0/31.0).astype(np.uint8) g = (((arr & 0x07E0) >>5) *255.0/63.0).astype(np.uint8) b = (((arr & 0x001F) >>0) *255.0/31.0).astype(np.uint8) buff = np.column_stack((r,g,b)) + size = w * h * 2 else: # JPEG try: buff = np.asarray(Image.frombuffer("RGB", (w, h), buff, "jpeg", "RGB", "")) @@ -110,7 +112,7 @@ def read_state(): if (buff.size != (w*h*3)): raise ValueError(f"Unexpected frame size. Expected: {w*h*3} received: {buff.size}") - return w, h, buff.reshape((h, w, 3)), text + return w, h, buff.reshape((h, w, 3)), size, text def fb_dump(): diff --git a/tools/pyopenmv_bench.py b/tools/pyopenmv_bench.py new file mode 100755 index 000000000..0a844a452 --- /dev/null +++ b/tools/pyopenmv_bench.py @@ -0,0 +1,110 @@ +#!/usr/bin/env python2 +# This file is part of the OpenMV project. +# +# Copyright (c) 2013-2021 Ibrahim Abdelkader +# Copyright (c) 2013-2021 Kwabena W. Agyeman +# +# This work is licensed under the MIT license, see the file LICENSE for details. +# +# An example script using pyopenmv to grab the framebuffer. + +import sys +import numpy as np +import pygame +import pyopenmv +from time import sleep + + +script = """ +import sensor, image, time + + +sensor.reset() # Reset and initialize the sensor. +sensor.set_pixformat(sensor.RGB565) # Set pixel format to RGB565 (or GRAYSCALE) +sensor.set_framesize(sensor.VGA) # Set frame size to QVGA (320x240) + +img = sensor.snapshot() # Take a picture and return the image. +img.compress() + +while(True): + img.flush() +""" + +# init pygame +pygame.init() + +if len(sys.argv)!= 2: + print ('usage: pyopenmv_fb.py ') + sys.exit(1) + +connected = False +portname = sys.argv[1] + +pyopenmv.disconnect() +for i in range(10): + try: + # opens CDC port. + # Set small timeout when connecting + pyopenmv.init(portname, baudrate=921600, timeout=0.050) + connected = True + break + except Exception as e: + connected = False + sleep(0.100) + +if not connected: + print("Failed to connect to OpenMV's serial port.\n" + "Please install OpenMV's udev rules first:\n" + "sudo cp openmv/udev/50-openmv.rules /etc/udev/rules.d/\n" + "sudo udevadm control --reload-rules\n\n") + sys.exit(1) + +# Set higher timeout after connecting for lengthy transfers. +pyopenmv.set_timeout(1*2) # SD Cards can cause big hicups. +pyopenmv.enable_fb(True) +pyopenmv.exec_script(script) + +# init screen +running = True +screen = None + +clock = pygame.time.Clock() +fps_clock = pygame.time.Clock() + +font = pygame.font.SysFont("monospace", 50) +fb_size = 0 + +try: + while running: + data = None + # Read state + w, h, data, size, text = pyopenmv.read_state() + + if text is not None: + print(text, end="") + + if data is not None: + fps = fps_clock.get_fps() + fps_clock.tick(500) + + if screen is None: + screen = pygame.display.set_mode((640, 120), pygame.DOUBLEBUF, 32) + + screen.fill((0, 0, 0)) + screen.blit(font.render("FPS %.2f %.2f MB/s"%(fps, fps * size / 1024**2), 1, (255, 0, 0)), (0, 30)) + + # update display + pygame.display.flip() + + for event in pygame.event.get(): + if event.type == pygame.QUIT: + running = False + elif event.type == pygame.KEYDOWN: + if event.key == pygame.K_ESCAPE: + running = False + clock.tick(500) +except KeyboardInterrupt: + pass + +pygame.quit() +pyopenmv.stop_script() diff --git a/tools/pyopenmv_fb.py b/tools/pyopenmv_fb.py index 022452c9e..da44ce721 100755 --- a/tools/pyopenmv_fb.py +++ b/tools/pyopenmv_fb.py @@ -74,20 +74,21 @@ running = True screen = None IMAGE_SCALE = 4 -Clock = pygame.time.Clock() -font = pygame.font.SysFont("monospace", 25) +clock = pygame.time.Clock() +fps_clock = pygame.time.Clock() +font = pygame.font.SysFont("monospace", 50) try: while running: - Clock.tick(30) # Read state - w, h, data, text = pyopenmv.read_state() + w, h, data, size, text = pyopenmv.read_state() if text is not None: print(text, end="") if data is not None: - fps = Clock.get_fps() + fps = fps_clock.get_fps() + # Create image from RGB888 image = pygame.image.frombuffer(data.flat[0:], (w, h), 'RGB') image = pygame.transform.scale(image, (w * IMAGE_SCALE, h * IMAGE_SCALE)) @@ -97,9 +98,11 @@ try: # blit stuff screen.blit(image, (0, 0)) - screen.blit(font.render("FPS %.2f"%(fps), 1, (255, 0, 0)), (0, 0)) + screen.blit(font.render("%.2f FPS %.2f MB/s"%(fps, fps * size / 1024**2), 5, (255, 0, 0)), (0, 0)) + # update display pygame.display.flip() + fps_clock.tick(250) for event in pygame.event.get(): if event.type == pygame.QUIT: @@ -109,6 +112,8 @@ try: running = False if event.key == pygame.K_c: pygame.image.save(image, "capture.png") + + clock.tick(250) except KeyboardInterrupt: pass