Error: "Sensor Control Failed": sensor.set_framesize(sensor.QQQVGA) on OpenMV N6

csi0.framesize(csi.QQQVGA) returns an error on OpenMV N6.
csi0.framesize(csi.QQVGA) returns an error on OpenMV N6.

csi0.framesize(csi.QVGA) does not return the error.

Can OpenMV N6 run the smaller resolution or can’t it?

Right now it does not support smaller resolutions with the PAG7936. We will potentially be able to support these in the future using the onboard image scaler in the N6’s ISP. But, not right now.

Thank you… My only reason for wanting the lower frame rate is from comparing with examples from a few years ago. Does the more recent N6 board with PAG7936 camera handle the larger images fast enough that there is no reason to set it for a lower resolution?
Or should I have chosen an older model for the lower resolution image?

(I’m trying linear regression to follow a line. No success yet.)

Yes, the N6 has much more performance. Please use Tools→Install the Latest Dev release if you have not.

Also, we are about to merge a massive performance update to all algorithms via the: misc: Add Unified Memory Allocator (UMA) based on TLSF. by iabdalkader · Pull Request #3036 · openmv/openmv · GitHub

Which linear regression algorithm are you trying to use? The robust one? That one should be a lot faster once we get this update done.

Also, you can just scale an image to reduce the res.

img.scale(x_scale=0.5, y_scale=0.5)

Thank you.

I’m currently working through the “Latest Dev Release” based on your advice. LED is solid green. Restarting windows and will try again to connect…

Thank you for your advice so far!

I’ve installed the latest release… The bottom of my screen shows Firmware Version 5.0.0
Incidentally I now need to unplug/plug my USB cable while the screen shows *“Connecting… click cancel if this takes more than 5 seconds.”

I opened Example –> Feature Detection –> Linear Regression (Robust)

As per the original issue on this thread, I changed this line:
(sensor.set_framesize(sensor.QQQVGA)
to this:
(sensor.set_framesize(sensor.QVGA)

After displaying the frame buffer aka live feed for 1-2 seconds, it freezes up.

I’ve also tried this:
img = sensor.snapshot().binary([THRESHOLD]) if BINARY_VISIBLE else sensor.snapshot()
img.scale(x_scale=0.5, y_scale=0.5)

Is there anything else that I can do?

# This work is licensed under the MIT license.
# Copyright (c) 2013-2023 OpenMV LLC. All rights reserved.
# https://github.com/openmv/openmv/blob/master/LICENSE
#
# Robust Linear Regression Example
#
# This example shows off how to use the get_regression() method on your OpenMV Cam
# to get the linear regression of a ROI. Using this method you can easily build
# a robot which can track lines which all point in the same general direction
# but are not actually connected. Use find_blobs() on lines that are nicely
# connected for better filtering options and control.
#
# We're using the robust=True argument for get_regression() in this script which
# computes the linear regression using a much more robust algorithm... but potentially
# much slower. The robust algorithm runs in O(N^2) time on the image. So, YOU NEED
# TO LIMIT THE NUMBER OF PIXELS the robust algorithm works on or it can actually
# take seconds for the algorithm to give you a result... THRESHOLD VERY CAREFULLY!

import sensor
import time

THRESHOLD = (0, 100)  # Grayscale threshold for dark things.
BINARY_VISIBLE = True  # Binary pass first to see what linear regression is running on.

sensor.reset()
sensor.set_pixformat(sensor.GRAYSCALE)
sensor.set_framesize(sensor.QVGA)  # 80x60 (4,800 pixels) - O(N^2) max = 2,3040,000.
sensor.skip_frames(time=2000)  # WARNING: If you use QQVGA it may take seconds
clock = time.clock()  # to process a frame sometimes.

while True:
    clock.tick()
    img = sensor.snapshot().scale(x_scale=0.25, y_scale=0.25)
    img.binary([THRESHOLD]) if BINARY_VISIBLE else sensor.snapshot()

    # Returns a line object similar to line objects returned by find_lines() and
    # find_line_segments(). You have x1(), y1(), x2(), y2(), length(),
    # theta() (rotation in degrees), rho(), and magnitude().
    #
    # magnitude() represents how well the linear regression worked. It means something
    # different for the robust linear regression. In general, the larger the value the
    # better...
    line = img.get_regression(
        [(255, 255) if BINARY_VISIBLE else THRESHOLD], robust=True
    )

    if line:
        img.draw_line(line.line(), color=127)
    print(
        "FPS %f, mag = %s" % (clock.fps(), str(line.magnitude()) if (line) else "N/A")
    )

# About negative rho values:
#
# A [theta+0:-rho] tuple is the same as [theta+180:+rho].

Yeah, 80x60 is still the right res to run at. I get 21 FPS. We’ll have some updates coming for memory access that will unlock 160x120, but, not 320x240.

Note that the algorithm works best when pointed at a line. You can raise the res a bit if you do. It’s an N^2 algorithm. So, the speed varies widely depending on the pixels that are in the regression. 80x60 res puts a hard cap on the total. When you go to 160x120 there’s no more hard cap so it’s scene dependent.

I did some more testing on this, yeah, 4096 points if all active at the same time will crush you down to 3fps. 1K points gets about 71 fps. 512 points is 120 fps. This is with our new memory allocator we are working on and putting the points in the N6’s DTCM (it’s fastest memory).

80x60 is 4800 points at max. So, yes, the right thing to do for this algorithm is to scale the image down to this size or smaller and run it on that reduced res image.

This is not a fix for the speed or image size, but if you install the latest dev now it should never crash again on high resolutions, it will just run extremely slow.