How to use the Raspicam on a Raspberry Pi 4B with Ubuntu 24 Server
https://askubuntu.com/questions/1567475/how-to-use-the-raspicam-on-a-raspberry-pi-4b-with-ubuntu-24-server

I'm encountering difficulties running the Raspicam on Ubuntu 24.04.4 LTS Server
I got the raspicam working by compiling libcamera from source, then using MJPG webserver streaming. latency is good at less than 150ms but is CPU heavy. it's 350mA idle, and 700mA when streaming.. So ?m sure the pipeline can work.
I ought to be using the hardware h264 encoder and stream h264
I attempted to do it with OpenCV. My plan is to use the V4L2 linux driver without libcamera, and open the media sources with opencv. Get a stream from /dev/video0 feed it to the transcoder /dev/video10 take the frames and send the stream this way.
(.venv) sona@rpi4-orso-sdbh:~/HowTo-Ubuntu24S-Raspicam-Webserver-Streaming$ v4l2-ctl --list-devices
bcm2835-codec-decode (platform:bcm2835-codec):
/dev/video10
/dev/video11
/dev/video12
/dev/video18
/dev/video31
/dev/media3
bcm2835-isp (platform:bcm2835-isp):
/dev/video13
/dev/video14
/dev/video15
/dev/video16
/dev/video20
/dev/video21
/dev/video22
/dev/video23
/dev/media1
/dev/media4
unicam (platform:fe801000.csi):
/dev/video0
/dev/media2
rpivid (platform:rpivid):
/dev/video19
/dev/media0
OpenCV does open the camera, but I only get black frames, and I don't understand why...
"""
uv pip install opencv-python-headless
python demo-opencv-snap-still.py
"""
import subprocess
import cv2
import numpy as np
DEVICE = "/dev/video0"
#DEVICE = "/dev/media0"
NUM_FRAMES = 10
print(f"\n=== Inspecting {DEVICE} ===\n")
# --- 1. Device info ---------------------------------------------------------
def print_device_info(dev):
print("Device info:")
try:
out = subprocess.check_output(
["v4l2-ctl", "-d", dev, "--info"],
stderr=subprocess.STDOUT
).decode()
print(out)
except Exception as e:
print(" Could not read device info:", e)
# --- 2. Supported resolutions -----------------------------------------------
def print_resolutions(dev):
print("Supported formats & resolutions:")
try:
out = subprocess.check_output(
["v4l2-ctl", "-d", dev, "--list-formats-ext"],
stderr=subprocess.STDOUT
).decode()
print(out)
except Exception as e:
print(" Could not list resolutions:", e)
# --- 3. OpenCV capture + brightness test ------------------------------------
def test_capture(dev):
print(f"\nOpening {dev} with OpenCV...\n")
cap = cv2.VideoCapture(dev)
if not cap.isOpened():
print("ERROR: OpenCV cannot open device")
return
# --- Show what OpenCV actually selected ---
w = cap.get(cv2.CAP_PROP_FRAME_WIDTH)
h = cap.get(cv2.CAP_PROP_FRAME_HEIGHT)
fourcc = int(cap.get(cv2.CAP_PROP_FOURCC))
fmt = "".join([chr((fourcc >> 8*i) & 0xFF) for i in range(4)])
print(f"OpenCV selected resolution: {int(w)}x{int(h)}")
print(f"OpenCV selected pixel format: {fmt}")
brightness_values = []
last_frame = None
for i in range(NUM_FRAMES):
ret, frame = cap.read()
if not ret:
print(f"Frame {i}: FAILED")
continue
print("Frame shape:", frame.shape, "dtype:", frame.dtype)
print("First 32 bytes:", frame.flatten()[:32])
last_frame = frame
gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
brightness = float(np.mean(gray))
brightness_values.append(brightness)
print(f"Frame {i}: brightness={brightness:.2f}")
cap.release()
if brightness_values:
avg = sum(brightness_values) / len(brightness_values)
print(f"\nAverage brightness: {avg:.2f}")
else:
print("No valid frames captured.")
if last_frame is not None:
cv2.imwrite("test.jpg", last_frame)
print("Saved test.jpg")
# --- Run all diagnostics ----------------------------------------------------
print_device_info(DEVICE)
print_resolutions(DEVICE)
test_capture(DEVICE)
(.venv) sona@rpi4-orso-sdl:~/HowTo-Ubuntu24S-Raspicam-Webserver-Streaming$ python demo-opencv-snap-still.py
=== Inspecting /dev/video0 ===
Device info:
Driver Info:
Driver name : unicam
Card type : unicam
Bus info : platform:fe801000.csi
Driver version : 6.8.12
Capabilities : 0xa5a00001
Video Capture
Metadata Capture
I/O MC
Read/Write
Streaming
Extended Pix Format
Device Capabilities
Device Caps : 0x25200001
Video Capture
I/O MC
Read/Write
Streaming
Extended Pix Format
Media Driver Info:
Driver name : unicam
Model : unicam
Serial :
Bus info : platform:fe801000.csi
Media version : 6.8.12
Hardware revision: 0x00000000 (0)
Driver version : 6.8.12
Interface Info:
ID : 0x03000005
Type : V4L Video
Entity Info:
ID : 0x00000003 (3)
Name : unicam-image
Function : V4L2 I/O
Flags : default
Pad 0x01000004 : 0: Sink
Link 0x02000007: from remote pad 0x1000002 of entity 'ov5647 10-0036' (Camera Sensor): Data, Enabled, Immutable
Supported formats & resolutions:
ioctl: VIDIOC_ENUM_FMT
Type: Video Capture
[0]: 'YUYV' (YUYV 4:2:2)
Size: Stepwise 16x16 - 16376x16376 with step 1/1
[1]: 'UYVY' (UYVY 4:2:2)
Size: Stepwise 16x16 - 16376x16376 with step 1/1
[2]: 'YVYU' (YVYU 4:2:2)
Size: Stepwise 16x16 - 16376x16376 with step 1/1
[3]: 'VYUY' (VYUY 4:2:2)
Size: Stepwise 16x16 - 16376x16376 with step 1/1
[4]: 'RGBP' (16-bit RGB 5-6-5)
Size: Stepwise 16x16 - 16376x16376 with step 1/1
[5]: 'RGBR' (16-bit RGB 5-6-5 BE)
Size: Stepwise 16x16 - 16376x16376 with step 1/1
[6]: 'RGBO' (16-bit A/XRGB 1-5-5-5)
Size: Stepwise 16x16 - 16376x16376 with step 1/1
[7]: 'RGBQ' (16-bit A/XRGB 1-5-5-5 BE)
Size: Stepwise 16x16 - 16376x16376 with step 1/1
[8]: 'RGB3' (24-bit RGB 8-8-8)
Size: Stepwise 16x16 - 16376x16376 with step 1/1
[9]: 'BGR3' (24-bit BGR 8-8-8)
Size: Stepwise 16x16 - 16376x16376 with step 1/1
[10]: 'RGB4' (32-bit A/XRGB 8-8-8-8)
Size: Stepwise 16x16 - 16376x16376 with step 1/1
[11]: 'BA81' (8-bit Bayer BGBG/GRGR)
Size: Stepwise 16x16 - 16376x16376 with step 1/1
[12]: 'GBRG' (8-bit Bayer GBGB/RGRG)
Size: Stepwise 16x16 - 16376x16376 with step 1/1
[13]: 'GRBG' (8-bit Bayer GRGR/BGBG)
Size: Stepwise 16x16 - 16376x16376 with step 1/1
[14]: 'RGGB' (8-bit Bayer RGRG/GBGB)
Size: Stepwise 16x16 - 16376x16376 with step 1/1
[15]: 'pBAA' (10-bit Bayer BGBG/GRGR Packed)
Size: Stepwise 16x16 - 16376x16376 with step 1/1
[16]: 'BG10' (10-bit Bayer BGBG/GRGR)
Size: Stepwise 16x16 - 16376x16376 with step 1/1
[17]: 'pGAA' (10-bit Bayer GBGB/RGRG Packed)
Size: Stepwise 16x16 - 16376x16376 with step 1/1
[18]: 'GB10' (10-bit Bayer GBGB/RGRG)
Size: Stepwise 16x16 - 16376x16376 with step 1/1
[19]: 'pgAA' (10-bit Bayer GRGR/BGBG Packed)
Size: Stepwise 16x16 - 16376x16376 with step 1/1
[20]: 'BA10' (10-bit Bayer GRGR/BGBG)
Size: Stepwise 16x16 - 16376x16376 with step 1/1
[21]: 'pRAA' (10-bit Bayer RGRG/GBGB Packed)
Size: Stepwise 16x16 - 16376x16376 with step 1/1
[22]: 'RG10' (10-bit Bayer RGRG/GBGB)
Size: Stepwise 16x16 - 16376x16376 with step 1/1
[23]: 'pBCC' (12-bit Bayer BGBG/GRGR Packed)
Size: Stepwise 16x16 - 16376x16376 with step 1/1
[24]: 'BG12' (12-bit Bayer BGBG/GRGR)
Size: Stepwise 16x16 - 16376x16376 with step 1/1
[25]: 'pGCC' (12-bit Bayer GBGB/RGRG Packed)
Size: Stepwise 16x16 - 16376x16376 with step 1/1
[26]: 'GB12' (12-bit Bayer GBGB/RGRG)
Size: Stepwise 16x16 - 16376x16376 with step 1/1
[27]: 'pgCC' (12-bit Bayer GRGR/BGBG Packed)
Size: Stepwise 16x16 - 16376x16376 with step 1/1
[28]: 'BA12' (12-bit Bayer GRGR/BGBG)
Size: Stepwise 16x16 - 16376x16376 with step 1/1
[29]: 'pRCC' (12-bit Bayer RGRG/GBGB Packed)
Size: Stepwise 16x16 - 16376x16376 with step 1/1
[30]: 'RG12' (12-bit Bayer RGRG/GBGB)
Size: Stepwise 16x16 - 16376x16376 with step 1/1
[31]: 'pBEE' (14-bit Bayer BGBG/GRGR Packed)
Size: Stepwise 16x16 - 16376x16376 with step 1/1
[32]: 'BG14' (14-bit Bayer BGBG/GRGR)
Size: Stepwise 16x16 - 16376x16376 with step 1/1
[33]: 'pGEE' (14-bit Bayer GBGB/RGRG Packed)
Size: Stepwise 16x16 - 16376x16376 with step 1/1
[34]: 'GB14' (14-bit Bayer GBGB/RGRG)
Size: Stepwise 16x16 - 16376x16376 with step 1/1
[35]: 'pgEE' (14-bit Bayer GRGR/BGBG Packed)
Size: Stepwise 16x16 - 16376x16376 with step 1/1
[36]: 'GR14' (14-bit Bayer GRGR/BGBG)
Size: Stepwise 16x16 - 16376x16376 with step 1/1
[37]: 'pREE' (14-bit Bayer RGRG/GBGB Packed)
Size: Stepwise 16x16 - 16376x16376 with step 1/1
[38]: 'RG14' (14-bit Bayer RGRG/GBGB)
Size: Stepwise 16x16 - 16376x16376 with step 1/1
[39]: 'BYR2' (16-bit Bayer BGBG/GRGR)
Size: Stepwise 16x16 - 16376x16376 with step 1/1
[40]: 'GB16' (16-bit Bayer GBGB/RGRG)
Size: Stepwise 16x16 - 16376x16376 with step 1/1
[41]: 'GR16' (16-bit Bayer GRGR/BGBG)
Size: Stepwise 16x16 - 16376x16376 with step 1/1
[42]: 'RG16' (16-bit Bayer RGRG/GBGB)
Size: Stepwise 16x16 - 16376x16376 with step 1/1
[43]: 'GREY' (8-bit Greyscale)
Size: Stepwise 16x16 - 16376x16376 with step 1/1
[44]: 'Y10P' (10-bit Greyscale (MIPI Packed))
Size: Stepwise 16x16 - 16376x16376 with step 1/1
[45]: 'Y10 ' (10-bit Greyscale)
Size: Stepwise 16x16 - 16376x16376 with step 1/1
[46]: 'Y12P' (12-bit Greyscale (MIPI Packed))
Size: Stepwise 16x16 - 16376x16376 with step 1/1
[47]: 'Y12 ' (12-bit Greyscale)
Size: Stepwise 16x16 - 16376x16376 with step 1/1
[48]: 'Y14P' (14-bit Greyscale (MIPI Packed))
Size: Stepwise 16x16 - 16376x16376 with step 1/1
[49]: 'Y14 ' (14-bit Greyscale)
Size: Stepwise 16x16 - 16376x16376 with step 1/1
[50]: 'Y16 ' (16-bit Greyscale)
Size: Stepwise 16x16 - 16376x16376 with step 1/1
Opening /dev/video0 with OpenCV...
OpenCV selected resolution: 640x480
OpenCV selected pixel format: BGR3
Frame shape: (480, 640, 3) dtype: uint8
First 32 bytes: [0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]
Frame 0: brightness=0.00
Frame shape: (480, 640, 3) dtype: uint8
First 32 bytes: [0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]
Frame 1: brightness=0.00
Frame shape: (480, 640, 3) dtype: uint8
First 32 bytes: [0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]
Frame 2: brightness=0.00
Frame shape: (480, 640, 3) dtype: uint8
First 32 bytes: [0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]
Frame 3: brightness=0.00
Frame shape: (480, 640, 3) dtype: uint8
First 32 bytes: [0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]
Frame 4: brightness=0.00
Frame shape: (480, 640, 3) dtype: uint8
First 32 bytes: [0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]
Frame 5: brightness=0.00
Frame shape: (480, 640, 3) dtype: uint8
First 32 bytes: [0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]
Frame 6: brightness=0.00
Frame shape: (480, 640, 3) dtype: uint8
First 32 bytes: [0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]
Frame 7: brightness=0.00
Frame shape: (480, 640, 3) dtype: uint8
First 32 bytes: [0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]
Frame 8: brightness=0.00
Frame shape: (480, 640, 3) dtype: uint8
First 32 bytes: [0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]
Frame 9: brightness=0.00
Average brightness: 0.00
Saved test.jpg
I added some diagnostics, and it seems to be imx219 V4L2 but I only grab black, and I don't understand why.
Frame snapped by the libcamera webserver streaming based script to test that hardware works

Frame snapped by the opencv based still script that is black. It seems to open the camera, but it just grabs black.

I'd like help understand what I'm doing wrong here.