Display real time image

Hello. I have OpenMV H7 Plus, Pan-tilt servo and LCD Shield. I encounter problem when I running the code for object detection and tracking. Pan-tilt and lcd are connected on the same pin which P7 and P8. Thus, I faced a conflict pin means when Lcd turn on, the servo unable to move. Since I am using the example code from OpenMV IDE and in the example code there is no define of number pin. Let say I change pin LCD for I2C to pin 4 and pin 5, is it the code still same? Below is my code

import sensor, image, time, os, ml, math, uos, gc, display
from ulab import numpy as np
from pyb import Servo
from pid import PID
import pyb


# Initialize pan and tilt servos
pan_servo = Servo(1)
tilt_servo = Servo(2)

# Servo calibration
pan_servo.calibration(500, 2500, 500)
tilt_servo.calibration(500, 2500, 500)

# PID parameters for smooth tracking
pan_pid = PID(p=0.2, i=0, imax=90)
tilt_pid = PID(p=0.2, i=0, imax=90)

# Initialize camera
sensor.reset()
sensor.set_pixformat(sensor.RGB565)
sensor.set_framesize(sensor.QQVGA2) # Modify as you like.
sensor.set_vflip(True)
sensor.skip_frames(time=2000)
sensor.set_auto_whitebal(False)

# Load ML model
net = None
labels = None
min_confidence = 0.7  # Confidence threshold

try:
    net = ml.Model("trained14.tflite", load_to_fb=uos.stat('trained14.tflite')[6] > (gc.mem_free() - (64*1024)))
except Exception as e:
    raise Exception('Failed to load "trained14.tflite". Copy the .tflite and labels14.txt files to the device. (' + str(e) + ')')

try:
    labels = [line.rstrip('\n') for line in open("labels14.txt")]
except Exception as e:
    raise Exception('Failed to load "labels14.txt". Copy the .tflite and labels14.txt files to the device. (' + str(e) + ')')

# Colors for different objects
colors = [(255, 0, 0), (0, 255, 0), (255, 255, 0), (0, 0, 255), (255, 0, 255), (0, 255, 255), (255, 255, 255)]


# Detection confidence threshold
threshold_list = [(math.ceil(min_confidence * 255), 255)]

def fomo_post_process(model, inputs, outputs):
    """Post-processing for FOMO object detection."""
    ob, oh, ow, oc = model.output_shape[0]
    x_scale = inputs[0].roi[2] / ow
    y_scale = inputs[0].roi[3] / oh
    scale = min(x_scale, y_scale)
    x_offset = ((inputs[0].roi[2] - (ow * scale)) / 2) + inputs[0].roi[0]
    y_offset = ((inputs[0].roi[3] - (ow * scale)) / 2) + inputs[0].roi[1]

    detections = [[] for _ in range(oc)]

    for i in range(oc):
        img = image.Image(outputs[0][0, :, :, i] * 255)
        blobs = img.find_blobs(threshold_list, x_stride=1, y_stride=1, area_threshold=1, pixels_threshold=1)
        for b in blobs:
            x, y, w, h = b.rect()
            score = img.get_statistics(thresholds=threshold_list, roi=b.rect()).l_mean() / 255.0
            x, y, w, h = int(x * scale + x_offset), int(y * scale + y_offset), int(w * scale), int(h * scale)
            detections[i].append((x, y, w, h, score))
    return detections

clock = time.clock()

lcd = display.SPIDisplay()

while True:
    lcd.write(sensor.snapshot())  # Take a picture and display the image.

    clock.tick()
    img = sensor.snapshot()

    largest_obj = None
    largest_area = 0
    detected_label = None

    # Process object detection
    for i, detection_list in enumerate(net.predict([img], callback=fomo_post_process)):
        if i == 0 or len(detection_list) == 0:  # Ignore background class or empty detections
            continue

        for x, y, w, h, score in detection_list:
            if score < min_confidence:
                continue  # Ignore low-confidence detections

            area = w * h
            if area > largest_area:
                largest_area = area
                largest_obj = (x, y, w, h)
                detected_label = labels[i] if i < len(labels) else "Unknown"

    if largest_obj:
        x, y, w, h = largest_obj
        centroid_x = x + w // 2
        centroid_y = y + h // 2

        # Draw tracking dot only
        img.draw_circle(centroid_x, centroid_y, 6, color=colors[i % len(colors)])

        # Center calculations
        img_center_x, img_center_y = img.width() / 2, img.height() / 2

        # Error calculation
        pan_error = centroid_x - img_center_x
        tilt_error = centroid_y - img_center_y

        # PID control
        pan_output = pan_pid.get_pid(pan_error, 1) / 2
        tilt_output = tilt_pid.get_pid(tilt_error, 1) /2
        print("pan_output:", pan_output)

        # Invert the pan PID output correctly
        pan_servo.angle(pan_servo.angle() + pan_output)

        # For tilt, the direction remains as originally coded.
        tilt_servo.angle(tilt_servo.angle() + tilt_output)


    print(f"FPS: {clock.fps()}")


Hi, the LCD shield pins are fixed.

If you want to move them you need to recompile the code for the board:

You just need to switch them to the correct CPU pin names you want to use:

Pin mapping to CPU name is here: micropython/ports/stm32/boards/OPENMV4P/pins.csv at 1a472061e9457236adc8ec148b4bf88c289aab52 · openmv/micropython · GitHub

Thanks for your reply. I already changed the code for pin that I want.

#define OMV_SPI_DISPLAY_RS_PIN                (&omv_pin_B11_GPIO)
#define OMV_SPI_DISPLAY_RST_PIN               (&omv_pin_B10_GPIO)
#define OMV_SPI_DISPLAY_BL_PIN                (&omv_pin_A5_GPIO)
#define OMV_SPI_DISPLAY_TRIPLE_BUFFER         (1)

For next step I am not sure how to do since I am still beginner. What I understand I need to recompile the code. It means change the firmware? Do you have tutorial video guide on to do this? I search on the google that I need to follow this step openmv/docs/firmware.md at master · openmv/openmv · GitHub. It quite complicated for me.

The readme explains what you have to do. It’s pretty much that.

The docker build is pretty easy.

Also, you can just fork the repo, then enable github actions, after you do this any edits and commits to the files in your fork will trigger the firmware to rebuild in the cloud. Then a development release will be generated with your changes.

Thanks for your assistance and finally it is working. I chose github rather than Docker (need to setup) because it is easy and just upload the firmware to IDE after changing the pin name in the code.