Get the video from Openmv H7 plus R4 camera

Hi, I am new to openmv board.

my boss purchased the camera from the below link

방금 AliExpress에서 찾은 상품이에요: ₩65,306 | H7 Plus 5MP HD 스마트 카메라 모듈 3.6-17V 32M SDRAM 오픈소스 비주얼 모듈 Type-C 인터페이스 OpenMV4와 호환 가능 https://a.aliexpress.com/_onAoIQd

I could not understand, how to get the video from this camera,

What I need is only video from the camera, no need other functionalities of the board, like line tracking … etc

this is a all belong came with camera

Please help me to get the video using opencv

Well, it’s not an official board from us. That’s definitely a clone. Anyway, we aren’t a webcam, if you want to use it for video with OpenCV that’s not what we do. You can still use it with OpenMV IDE and use the examples and etc.

Thank your for your quick response,

I want to know that

right now boar has a camera right?

What is the supported resolutions and fps for the camera?

does it support 1080p at 30fps?

Yes, you could use the pyopenmv_fb.py script in our tools directoy to pull jpeg images from the camera if you want. openmv/tools/pyopenmv_fb.py at master · openmv/openmv · GitHub

Modify the script inside of the file above to say:

import sensor, image, time
sensor.reset()
sensor.set_pixformat(sensor.JPEG)
sensor.set_framesize(sensor.FHD)
sensor.skip_frames(time = 2000)
clock = time.clock()

while(True):
    clock.tick()
    img = sensor.snapshot()
    print(clock.fps(), " FPS")

when I connect the board to my pc, my pc recognizes memory card connected which has 34MB of memory, in it, there is a main.py file contains

# main.py -- put your code here!

import pyb, time

led = pyb.LED(3)

usb = pyb.USB_VCP()

while (usb.isconnected()==False):

led.on()

time.sleep_ms(150)

led.off()

time.sleep_ms(100)

led.on()

time.sleep_ms(150)

led.off()

time.sleep_ms(600)

I have modified this code to
import sensor, time, sys

sensor.reset()
sensor.set_framesize(sensor.FHD)
sensor.set_pixformat(sensor.JPEG)
sensor.skip_frames(time=2000)
sensor.set_auto_gain(False)
sensor.set_auto_whitebal(False)

while True:
img = sensor.snapshot()
compressed = img.compress(quality=30)

print("FRAME_START")
print(len(compressed))
sys.stdout.buffer.write(compressed)
print("\nFRAME_END")

and then in my pc

#!/usr/bin/env python3

import serial

import time

import cv2

import numpy as np

import threading

from collections import deque

class OpenMVStreamer:

def _init_(self, port=‘/dev/ttyACM0’, baudrate=115200):

self.ser = serial.Serial(port, baudrate, timeout=0.1, dsrdtr=False)

self.frame_buffer = deque(maxlen=5)

self.running = False

self.frame_count = 0

self.last_frame = None # Store last frame for saving original resolution

def start_streaming(self):

self.running = True

self.stream_thread = threading.Thread(target=self._stream_worker)

self.stream_thread.daemon = True

self.stream_thread.start()

def _stream_worker(self):

buffer = b""

while self.running:

try:

if self.ser.in_waiting > 0:

data = self.ser.read(self.ser.in_waiting)

buffer += data

while b"FRAME_START\r\n" in buffer and b"\r\nFRAME_END\r\n" in buffer:

start_idx = buffer.find(b"FRAME_START\r\n")

end_idx = buffer.find(b"\r\nFRAME_END\r\n")

if start_idx < end_idx:

frame_data = buffer[start_idx:end_idx + len(b"\r\nFRAME_END\r\n")]

buffer = buffer[end_idx + len(b"\r\nFRAME_END\r\n"):]

frame = self._parse_frame(frame_data)

if frame is not None:

self.last_frame = frame.copy() # Store original frame

self.frame_buffer.append(frame)

else:

break

time.sleep(0.001)

except Exception as e:

print(f"Stream error: {e}")

continue

def _parse_frame(self, frame_data):

try:

lines = frame_data.split(b’\r\n’)

if len(lines) >= 4 and lines[0] == b"FRAME_START":

size_str = lines[1].decode(‘utf-8’)

if size_str.isdigit():

frame_size = int(size_str)

img_start = frame_data.find(lines[1] + b’\r\n’) + len(lines[1]) + 2

img_end = frame_data.find(b’\r\nFRAME_END’)

if img_end > img_start:

img_data = frame_data[img_start:img_end]

if len(img_data) == frame_size:

nparr = np.frombuffer(img_data, np.uint8)

frame = cv2.imdecode(nparr, cv2.IMREAD_COLOR)

return frame

except Exception as e:

print(f"Parse error: {e}")

return None

def get_frame(self):

if self.frame_buffer:

self.frame_count += 1

return self.frame_buffer.popleft()

return None

def stop(self):

self.running = False

if hasattr(self, ‘stream_thread’):

self.stream_thread.join(timeout=1)

self.ser.close()

def main():

print(“Starting OpenMV video stream…”)

print(“Controls:”)

print(" ‘q’ - Quit")

print(" ‘s’ - Save original resolution frame")

print(" ‘d’ - Save display resolution frame")

streamer = OpenMVStreamer()

streamer.start_streaming()

fps_counter = 0

fps_start = time.time()

try:

while True:

frame = streamer.get_frame()

if frame is not None:

fps_counter += 1

# Get original dimensions

original_height, original_width = frame.shape[:2]

# Calculate FPS

current_time = time.time()

elapsed = current_time - fps_start

if elapsed >= 1.0:

fps = fps_counter / elapsed

print(f"FPS: {fps:.1f} | Resolution: {original_width}x{original_height}")

fps_counter = 0

fps_start = current_time

# Resize for display

display_frame = cv2.resize(frame, (640, 480))

# Add information overlay

cv2.putText(display_frame, f"Frame: {streamer.frame_count}", (10, 30),

cv2.FONT_HERSHEY_SIMPLEX, 0.7, (0, 255, 0), 2)

cv2.putText(display_frame, f"Original: {original_width}x{original_height}", (10, 60),

cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 255, 0), 1)

cv2.putText(display_frame, f"Display: 640x480", (10, 80),

cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 255, 0), 1)

cv2.putText(display_frame, “Press ‘s’ for original, ‘d’ for display, ‘q’ to quit”, (10, 460),

cv2.FONT_HERSHEY_SIMPLEX, 0.4, (255, 255, 255), 1)

cv2.imshow(‘OpenMV Video Stream’, display_frame)

key = cv2.waitKey(1) & 0xFF

if key == ord(‘q’):

break

elif key == ord(‘s’):

# Save original resolution

if streamer.last_frame is not None:

filename = f"openmv_original_{streamer.frame_count:04d}.jpg"

cv2.imwrite(filename, streamer.last_frame)

h, w = streamer.last_frame.shape[:2]

print(f"Saved original ({w}x{h}): {filename}")

elif key == ord(‘d’):

# Save display resolution

filename = f"openmv_display_{streamer.frame_count:04d}.jpg"

cv2.imwrite(filename, display_frame)

print(f"Saved display (640x480): {filename}")

else:

time.sleep(0.01)

except KeyboardInterrupt:

print(“\nStopping…”)

finally:

streamer.stop()

cv2.destroyAllWindows()

print(“Stream stopped”)

if _name_ == ‘_main_’:

main()

when I run this code, it gives me 1920x1080 with almost 5FPS

with 1280x720, almost 15FPS.

with 320x240, almost 45FPS

does it mean, 1920x1080 with 30FPS not supported right?

Yeah, the H7 Plus has a 12Mb/s USB connection, not 480 Mb/s. It can’t stream high res video quickly to the PC. This is a limitation of the hardware. It’s not really meant for this anyway.