RkBlog

Testing Raspberry Pi cameras with Sony and OmniVision CMOS sensors

2024-11-18

There is a lot of third party cameras for Raspberry Pi, Pi Zero or Nvidia Jetson boards using different Sony or OmniVision CMOS sensors. They offer different resolutions, framerates and sensitivity. I got few boards from Aliexpress, one official camera module and used all of them in few test shots presented below.

Raspberry Pi cameras connect via 15-pin tapes to the MIPI Camera Serial Interface (CSI) on the Raspberry Pi board. Pi Zero uses different, narrower tapes than the base Raspberry boards. Most camera modules will come with integrated lens, while few selected come with a C/CS thread for lenses. Those with an integrated lens can have fixed focus or an auto-focusing system present.

Cameras can be operated from command line with rpicam-still and rpicam-vid or through Python code with python3-picamzero. You can check a Raspberry Pi official guide if you want to know more.

from picamzero import Camera

cam = Camera()
cam.start_preview()
cam.take_photo("./new_image.jpg")
cam.stop_preview()
rpicam-still -o image.jpg

Note that the Bookworm/Bullseye OS will only detect the official modules - in my case Camera Module 3 and the OV5647 boards. For all other boards you will have to set manual configurations as described on docs.arducam.com.

I edited the /boot/firmware/config.txt and set sensor name and then shut down the RPi, connected the camera and booted RPi:

camera_auto_detect=0

[all]
dtoverlay=imx519

Below are test photos taken with each camera board on automatic settings of the camera.

Raspberry Pi Camera Module 3

The Camera Module 3 uses Sony IMX708 12-megapixel sensor. The variant I got is NoIR which means it has no IR-cut filter inside the lens assembly. Infrared blocking filters are used in color cameras to get accurate colors on images. For vision applications this may not be desired when infrared illumination is being used (like in some night vision system). Humans or animals can't see such infrared light but cameras can.

IMX708 offers a frame of 4608 x 2592 pixels and RAW10 output format. The image quality is quite good.

IMX708 camera module
IMX708 camera module
IMX708 - close range image
IMX708 - close range image
IMX708 - low light / night-time image
IMX708 - low light / night time image

OmniVision OV5647

OmniVision sensors are usually the cheapest, but they tend to fall behind Sony in terms of noise and image quality. OV5647 offers a frame of 2592 x 1944 pixels.

OV5647 custom boards
OV5647 custom boards
OV5647 Rev 1.3 board
OV5647 Rev 1.3 board
OV5647 - close range image
OV5647 - close range image
OV5647 with manual 3,6mm lens - close range image
OV5647 with manual 3,6mm lens - close range image

In well illuminated scene those camera modules had the tendency to over-expose the image. The 3,6mm lens also has some field curvature to it.

OV5647 - low light / night-time image
OV5647 - low light / night-time image
OV5647 - low light / night-time image

IMX219

IMX219 is an 8 mpix sensors with a frame of 3280 x 2464 pixels. This board came with a 160 degree widefield lens which as seen below has quite a lot of field curvature due to such large field of view.

IMX219 camera board
IMX219 camera board with a widefield lens
IMX219 - close range image
IMX219 - close range image
IMX219 - low light / night-time image
IMX219 - low light / night-time image

IMX290

IMX290 is a 2 mpix sensor with a frame of 1920 x 1080, and it got quite popular in planetary astrophotography cameras due to good performance and good value. Should be good for low light conditions as well as seen on the image below.

IMX290 camera board
IMX290 camera board
IMX290 - close range image
IMX290 - close range image
IMX290 - low light / night-time image
IMX290 - low light / night-time image

IMX477

IMX477 is a larger 12,3 mpix sensor with a 4056 x 3040 frame. This module came with a C/CS-lens thread and I used two of my lenses C/CS 16mm and C-mount 26mm.

IMX477 camera board and lenses
IMX477 camera board and lenses
IMX477 with 25mm lens - close range image
IMX477 with 25mm lens - close range image
IMX477 with 25mm lens - low light / night-time image
IMX477 with 25mm lens - low light / night-time image
IMX477 with 16mm lens - low light / night-time image
IMX477 with 16mm lens - low light / night-time image

With manual focus it was hard to get it perfect in night conditions with quite flimsy setup ;)

IMX519

IMX519 is a slightly larger 16 mpix sensor with a frame of 4656 x 3496 pixels and quite good performance.

IMX519 camera board and lenses
IMX519 camera board and lenses
IMX519 - close range image
IMX519 - close range image
IMX519 - low light / night-time image
IMX519 - low light / night-time image

IMX307

IMX307 is also a 1920 x 1080 low resolution sensor with good low light performance, however the board I got was made by Veye Imaging and is not compatible with libcamera and relies on old VideoCore APIs that the Raspberry Pi foundation abandoned some time ago - the board does not work on modern RPi systems.

Veye Imaging IMX307 camera board
Veye Imaging IMX307 camera board

Low light sensitivity versus what you see

Some of Sony sensors offer very low read noise which combined with very good sensitivity gives very good low light performance. Depending on sensor design this have marketing names like Starvis. If you want to do imaging in low light conditions you will likely want to control camera parameters like exposure time, gain manually to get the best results. In the above tests only IMX290 board got a good night-time image on fully automatic default model.

On top of that you may want to do some post-processing on such images like simple histogram clipping to expose every last detail possible (which also exposes noise). In astrophotography to remove fixed pattern noise and hot pixels the processing can be more advanced with dark frames or image stacking.

Canon EOS R50 night still shot
Canon EOS R50 night still shot
IMX290 - cropped histogram
IMX290 - cropped histogram
IMX519 - cropped histogram
IMX519 - cropped histogram

If the photographed scene is still you can increase exposure time to gett better signal in low light conditions. Picamera2 Python module can handle exposure time given in microseconds. Below is an example script that takes few photos at different exposure time from 0,125s to 3s:

import time
import cv2

from picamera2 import MappedArray, Picamera2, Preview

exposure_time = [3000000, 2000000, 1000000, 500000, 250000, 125000]
frame_size = (4608, 2592)  # set to your camera sensor frame size


picam2 = Picamera2()
config = picam2.create_still_configuration(main={"format": 'RGB888', "size": frame_size}, controls={"AwbEnable":0, "AwbMode": 4})
picam2.configure(config)


for exposure in exposure_time:
    picam2.set_controls({"ExposureTime": exposure, "AnalogueGain": 1.0})
    picam2.start()
    file_name = f"img_{str(exposure)}.jpg"
    picam2.capture_file(file_name)
    picam2.stop()

Rolling versus Global Shutter

All of showcased sensors use rolling shutter where data is read row by row. This can cause distortions when imaging fast moving objects. To limit this effect you would have to use shorter exposure which not always can be doable. An alternative could a sensor with a global shutter lime IMX174 but such sensors are more expensive and usually used in machine vision cameras (some vendors do provide APIs for various programming languages, which can include Python). From OmniVision boards you can look for OV7251 and OV9281.

If you want to know more about such cameras and camera vendors you can check my articles linked below:

Comment article