Raspberry Pi classify.py errors

I’ve been scratching my head on this over the past days, and can’t seem to figure it out. Any help would be greatly appreciated.

My setup currently runs a Raspberry Pi 4 model B, with a Raspberry Pi camera model 2. The OS I installed is Raspberry Pi 4 Legacy, 64 bit Full (Bullseye). I did not have a screen available, so had to set up using SSH and VNC, for reference in case this effects anything.

Since this is an M2 camera with RP4, I had to change the config.txt to include dtoverlay=imx219 in order to confirm the camera working using the command libcamera-hello. I was then able to use libcamera-still -o image.jpg to save the image taken onto home directory. However, I was not able to use raspistill and discovered libcamera stack replaced raspistill, and another stack named picamera2 was introduced as well. I eventually built my model and deployed it as “Linux (AARCH64)” since my intent is to have python scrips detect the results and respond accordingly (flash LED, record encounter, etc.).

I eventually installed the edge impulse SDK onto the RP, and was able to successfully run the model using edge-impulse-linux-runner. This is where my problems begin. Since I want the model to be ran within my own application in python, I referenced to tool provided within this website and eventually came across an example that grabs data from a webcam and classifies it in real-time.

The code can be found here: linux-sdk-python/examples/image/classify.py at master · edgeimpulse/linux-sdk-python · GitHub

When I try running this code, it seems like the example script is unable to find a the camera connected to the RP, even though the camera was being used correctly for use with the Edge Impulse model via command above. I tried to increase port range to 10, and used ls /dev/video* to list all video devices. The terminal showed the multiple ones ranging from 0 to 31. I then modified get_webcams() to the following:

def get_webcams():
    port_ids = []
    for port in range(32):  # Increased range up to 31
        print("Looking for a camera in port %s:" % port)
        camera = cv2.VideoCapture(port)
        if camera.isOpened():
            ret, frame = camera.read()
            if ret:
                backendName = camera.getBackendName()
                w = camera.get(3)
                h = camera.get(4)
                print("Camera %s (%s x %s) found in port %s " % (backendName, w, h, port))
                port_ids.append(port)
            else:
                print("Camera in port %s could not capture frames." % port)
            camera.release()
        else:
            print(f"Failed to open camera at port {port}.")
    return port_ids

This resulted in: ModuleNotFoundError: No module named 'pyaudio'

I installed PortAudio Libraries and PyAudio and decided to test again to eventually receive: Exception: Cannot find any webcams

I wasn’t sure what exactly was going on, but it seems like the script was unable to successfully access or initialize any of the camera devices on the RP. I checked through the RP config and double checked all updates again. I then attempted to see if I could directly access the camera with the following:

import cv2
from picamera2 import Picamera2
from edge_impulse_linux.image import ImageImpulseRunner

def test_camera(device_path):
    camera = cv2.VideoCapture(device_path)
    if camera.isOpened():
        ret, frame = camera.read()
        if ret:
            print(f"Successfully accessed {device_path}")
            cv2.imshow("Test Frame", frame)
            cv2.waitKey(0)
            cv2.destroyAllWindows()
        else:
            print(f"Failed to read from {device_path}")
        camera.release()
    else:
        print(f"Failed to open {device_path}")

test_camera('/base/soc/i2c0mux/i2c@1/imx219@10')

To which I obtained the device path from edge-impulse-linux-runner. The camera once again failed to open. I decided to switch things up and use the picamera2 library just to test if I could use the library’s configuration directly. I typed up the following code which was able to work:

from picamera2 import Picamera2

def capture_image():
    picam2 = Picamera2()
    picam2.configure(picam2.create_still_configuration())
    picam2.start()
    picam2.capture_file("test.jpg")
    print("Image captured as test.jpg")
    picam2.stop()

if __name__ == "__main__":
    capture_image()

Seeing how with works, I was wondering if I could use OpenCV to show a preview, but received this error even after installing the required packages:

cv2.error: OpenCV(4.9.0) /io/opencv/modules/highgui/src/window.cpp:1255: error: (-2:Unspecified error) The function is not implemented. Rebuild the library with Windows, GTK+ 2.x or Cocoa support. If you are on Ubuntu or Debian, install libgtk2.0-dev and pkg-config, then re-run cmake or configure script in function 'cvNamedWindow'

I even tried to rebuild OpenCV with GUI Support manually with no success. I then moved on assuming I could capture the image using “picamera2”, but received an error: TypeError: Object of type ndarray is not JSON serializable.

After running into this type of problem before, even trying many things such as converting the image data to Base64, I knew it was time to ask for help. I don’t quite understand how edge-impulse-linux-runner configures the model and accesses the camera when examples to classify real-time data do not. Classifying and image itself works using the example provided under tools. Yet, I can’t seem to get this camera to work under any circumstance for real-time classification.

My questions would be, what type of data does the runner exactly receive or need to successfully start classifying real-time images/video? If this requires the configuration of M2 camera, then what exactly is being used to detect this camera? Is there an example I could learn from?

Thank you for your patience!

Hi @Tyguy

Can we try to debug your camera connection first? It would be the most likely culprit.

  1. Verify Camera Connection:
  • Double-check the physical connection of the M2 camera to the Raspberry Pi. Ensure that the camera module is securely connected to the designated camera port on the Raspberry Pi board.
  1. Check Camera Initialization:
  • Confirm that the camera is initialized and recognized by the Raspberry Pi operating system. You can do this by running:
ls /dev/video*
  • Ensure that the M2 camera is listed among the detected video devices. If it’s not listed, there may be issues with the camera connection or driver installation.
  1. Test Camera Access with Basic Commands:
  • Utilize basic camera commands to verify access to the M2 camera:
libcamera-still -o test.jpg
  • This command should capture an image using the M2 camera and save it as “test.jpg” in the home directory. Check if the image is captured successfully.
  1. Verify Camera Access in Python:
  • Write a simple Python script to access the camera using OpenCV or the picamera2 library:
import cv2

camera = cv2.VideoCapture(0)
if camera.isOpened():
    ret, frame = camera.read()
    if ret:
        print("Camera accessed successfully.")
    else:
        print("Failed to capture frame from the camera.")
    camera.release()
else:
    print("Failed to open the camera.")
  • Save and run the above as a cameratest.py script and check if the camera is accessed successfully and if frames are captured without errors.

Please paste the outputs of the suggested and see if the connection is the problem

Best

Eoin

Hello Eoin

I typed in ls /dev/video* to receive the following:

/dev/video0   /dev/video12  /dev/video16  /dev/video21
/dev/video1   /dev/video13  /dev/video18  /dev/video22
/dev/video10  /dev/video14  /dev/video19  /dev/video23
/dev/video11  /dev/video15  /dev/video20  /dev/video31

There is no indication of M2 being recognized by the Pi. It seems like a driver issue most likely if there is nothing listed here.

Running libcamera-still -o test.jpg does work with the following output:

Made X/EGL preview window
[0:18:07.876439312] [1575]  INFO Camera camera_manager.cpp:297 libcamera v0.0.5+83-bde9b04f
[0:18:07.939100869] [1577]  WARN RPI vc4.cpp:383 Mismatch between Unicam and CamHelper for embedded data usage!
[0:18:07.940158088] [1577]  INFO RPI vc4.cpp:437 Registered camera /base/soc/i2c0mux/i2c@1/imx219@10 to Unicam device /dev/media1 and ISP device /dev/media2
[0:18:07.940279937] [1577]  INFO RPI pipeline_base.cpp:1101 Using configuration file '/usr/share/libcamera/pipeline/rpi/vc4/rpi_apps.yaml'
[0:18:07.942176879] [1575]  INFO Camera camera.cpp:1033 configuring streams: (0) 1640x1232-YUV420
[0:18:07.943370206] [1577]  INFO RPI vc4.cpp:565 Sensor: /base/soc/i2c0mux/i2c@1/imx219@10 - Selected sensor format: 1640x1232-SBGGR10_1X10 - Selected unicam format: 1640x1232-pBAA
[0:18:13.087624620] [1575]  INFO Camera camera.cpp:1033 configuring streams: (0) 3280x2464-YUV420 (1) 3280x2464-SBGGR10_CSI2P
[0:18:13.088529027] [1577]  INFO RPI vc4.cpp:565 Sensor: /base/soc/i2c0mux/i2c@1/imx219@10 - Selected sensor format: 3280x2464-SBGGR10_1X10 - Selected unicam format: 3280x2464-pBAA
Still capture image received

I am able to use libcamera-still and libcamera-vid without issues.

When running the Python script you provide, we get the following:

Failed to capture frame from the camera.

Which indicates the camera was opened, but was not able to capture a frame from camera.read(). I then checked what exactly is being returned from camera.read() and it displays the following:

(False, None)

I created another script to test if using picamera2 would be able to capture the image and it seems like it does:

from picamera2 import Picamera2
import numpy as np

picam2 = Picamera2()
picam2.configure(picam2.create_still_configuration())
picam2.start()
frame = picam2.capture_array()
if frame is not None:
    print("Camera accessed successfully.")
else:
    print("Failed to capture frame from the camera.")
picam2.stop()

Returning Camera accessed successfully.

Thank you for the swift reply and your time on this, I appreciate it greatly.

Hi @Tyguy,

It seems like there might be a permissions issue with accessing the camera. Try our guides troubleshooting steps to resolve this, you can confirm the permissions issue with step 1 and then follow step 2:

  1. Check USB Devices with lsusb: Run lsusb both with and without sudo to check if the camera is listed among the connected USB devices. This can help determine if the camera is detected by the system and whether it requires elevated privileges to access.
  2. Reinstall Edge Impulse CLI: Sometimes, issues can arise due to misconfigurations or incomplete installations. I recommend uninstalling and then reinstalling the Edge Impulse CLI following the instructions in the provided links. Pay close attention to any permissions-related guidance and ensure that you have the necessary permissions to access the camera:
    Edge Impulse CLI | Edge Impulse Documentation

Further troubleshooting steps here:

Best,

Eoin