Cannot open Picamera by index

Hi everyone, I want to create a drowsiness detector by using Raspberry Pi 4 model b, Picamera2 and an alarm buzzer but I cannot open a camera preview after I run my Python script. It keeps showing an error to me, looks like there is a problem with the index number, may I know how to check my Picamera2 index number?
I use bookworm OS

below is the code:

[0:03:00.542245672] [2552]  INFO Camera camera_manager.cpp:284 libcamera v0.1.0+118-563cd78e
[0:03:00.571168714] [2562]  WARN RPiSdn sdn.cpp:39 Using legacy SDN tuning - please consider moving SDN inside rpi.denoise
[0:03:00.573974638] [2562]  INFO RPI vc4.cpp:444 Registered camera /base/soc/i2c0mux/i2c@1/ov5647@36 to Unicam device /dev/media0 and ISP device /dev/media1
[0:03:00.574054305] [2562]  INFO RPI pipeline_base.cpp:1142 Using configuration file '/usr/share/libcamera/pipeline/rpi/vc4/rpi_apps.yaml'
[0:03:00.578403164] [2552]  INFO Camera camera_manager.cpp:284 libcamera v0.1.0+118-563cd78e
[0:03:00.606613276] [2565]  WARN RPiSdn sdn.cpp:39 Using legacy SDN tuning - please consider moving SDN inside rpi.denoise
[0:03:00.608878048] [2565]  INFO RPI vc4.cpp:444 Registered camera /base/soc/i2c0mux/i2c@1/ov5647@36 to Unicam device /dev/media0 and ISP device /dev/media1
[0:03:00.608954253] [2565]  INFO RPI pipeline_base.cpp:1142 Using configuration file '/usr/share/libcamera/pipeline/rpi/vc4/rpi_apps.yaml'
[0:03:00.614843528] [2552]  INFO Camera camera.cpp:1183 configuring streams: (0) 640x480-XRGB8888 (1) 640x480-SGBRG10_CSI2P
[0:03:00.615262457] [2565]  INFO RPI vc4.cpp:608 Sensor: /base/soc/i2c0mux/i2c@1/ov5647@36 - Selected sensor format: 640x480-SGBRG10_1X10 - Selected unicam format: 640x480-pGAA
[ WARN:0@2.620] global cap_v4l.cpp:997 open VIDEOIO(V4L2:/dev/video0): can't open camera by index
[ WARN:0@2.624] global obsensor_stream_channel_v4l2.cpp:82 xioctl ioctl: fd=67, req=-2140645888
[ WARN:0@2.624] global obsensor_stream_channel_v4l2.cpp:138 queryUvcDeviceInfoList ioctl error return: 25
[ERROR:0@2.626] global obsensor_uvc_stream_channel.cpp:159 getStreamChannelGroup Camera index out of range

This is my python script:

import cv2
import numpy as np
import dlib
from imutils import face_utils
from picamera2 import Picamera2
import RPi.GPIO as GPIO

buzzer_pin = 16

picam2 = Picamera2()
picam2.configure(picam2.create_video_configuration(main={"format": 'XRGB8888', "size": (640, 480)}))
picam2.start()

GPIO.setmode(GPIO.BOARD)
GPIO.setwarnings(False)
GPIO.setup(buzzer_pin, GPIO.OUT)
GPIO.output(buzzer_pin, GPIO.LOW)

cap = cv2.VideoCapture(0)

detector = dlib.get_frontal_face_detector()
predictor = dlib.shape_predictor("shape_predictor_68_face_landmarks.dat")

sleep = 0
drowsy = 0
active = 0
status = ""
color = (0, 0, 0)


def compute(ptA, ptB):
    dist = np.linalg.norm(ptA - ptB)
    return dist


def blinked(a, b, c, d, e, f):
    up = compute(b, d) + compute(c, e)
    down = compute(a, f)
    ratio = up/(2.0*down)

    if(ratio > 0.25):
        return 2
    elif(ratio > 0.21 and ratio <= 0.25):
        return 1
    else:
        return 0


while True:
    frame = vs.read()
    frame = imutils.resize(frame, width=450)
    gray = cv2.cvtColor(im, cv2.COLOR_BGR2GRAY)

    faces = detector(gray)
    face_frame = frame.copy()

    for face in faces:
        x1 = face.left()
        y1 = face.top()
        x2 = face.right()
        y2 = face.bottom()

        
        cv2.rectangle(face_frame, (x1, y1), (x2, y2), (0, 255, 0), 2)

        landmarks = predictor(gray, face)
        landmarks = face_utils.shape_to_np(landmarks)

        left_blink = blinked(landmarks[36], landmarks[37],
                             landmarks[38], landmarks[41], landmarks[40], landmarks[39])
        right_blink = blinked(landmarks[42], landmarks[43],
                              landmarks[44], landmarks[47], landmarks[46], landmarks[45])


        if(left_blink == 0 or right_blink == 0):
            sleep += 1
            drowsy = 0
            active = 0
            if(sleep > 6):
                status = "SLEEPING !!!"
                color = (255, 0, 0)
                GPIO.output(buzzer_pin, GPIO.HIGH)

        elif(left_blink == 1 or right_blink == 1):
            sleep = 0
            active = 0
            drowsy += 1
            if(drowsy > 6):
                status = "Drowsy !"
                color = (0, 0, 255)
                GPIO.output(buzzer_pin, GPIO.HIGH)

        else:
            drowsy = 0
            sleep = 0
            active += 1
            if(active > 6):
                status = "Active :)"
                color = (0, 255, 0)
                GPIO.output(buzzer_pin, GPIO.LOW)

        cv2.putText(frame, status, (100, 100),
                    cv2.FONT_HERSHEY_SIMPLEX, 1.2, color, 3)

        for n in range(0, 68):
            (x, y) = landmarks[n]
            cv2.circle(face_frame, (x, y), 1, (255, 255, 255), -1)

    cv2.imshow("Frame", frame)
    cv2.imshow("Result of detector", face_frame)
    key = cv2.waitKey(1)
    if key == 27:
        break

Please help me! Also, if you think where my code can revised for a better version, please comment to let me know.

Hi @cheeyun

Here are a couple of steps you can try to debug the camera connection:

  1. Ensure Camera Connection: Make sure your PiCamera is correctly connected to the Raspberry Pi. If you are using a camera module like PiCamera, ensure it is properly attached to the CSI (Camera Serial Interface) port of the Raspberry Pi.
  2. Enable Camera Interface: On Raspberry Pi, you need to enable the camera interface from the configuration settings. You can do this by running sudo raspi-config, navigating to Interface Options, then Camera, and enabling it. After enabling, reboot your Raspberry Pi.
  3. Check Camera Status: You can check if the Raspberry Pi recognizes the camera by using the vcgencmd get_camera command. If properly connected and recognized, it should display supported=1 detected=1.
  4. Use Correct Camera API: Since you are using PiCamera2, it is designed to work with the libcamera library. OpenCV, by default, tries to access cameras using V4L2 (Video4Linux2). Ensure your code uses the appropriate library to access the camera. For libcamera-based cameras like PiCamera2, you might not use OpenCV’s cv2.VideoCapture() directly but rather follow the PiCamera2 library’s methods to capture images or video.
  5. Check for Conflicting Processes: The error logs mention gst-launch-1.0 which is part of GStreamer, a pipeline-based multimedia framework that might be accessing the camera. Ensure no other process is using the camera by running fuser /dev/video0 or lsof /dev/video0 to list any processes accessing the camera device. If you find any, consider stopping those processes.
  6. Permissions: Ensure your user has the necessary permissions to access the video device. You can temporarily test this by running your script with sudo to see if it’s a permissions issue. If it works with sudo, you might need to add your user to the appropriate group (usually video) that has access to the camera device: sudo usermod -a -G video $USER. Afterward, log out and log back in for the changes to take effect.

Best

Eoin