Skip to content

Instantly share code, notes, and snippets.

@Hermann-SW
Last active May 9, 2024 02:31
Show Gist options
  • Save Hermann-SW/e6049fe1a24fc2b5a53c654e0e9f6b9c to your computer and use it in GitHub Desktop.
Save Hermann-SW/e6049fe1a24fc2b5a53c654e0e9f6b9c to your computer and use it in GitHub Desktop.
tool for playing with Raspberry Pi Global Shutter Camera crop values
#!/bin/bash
# shellcheck disable=SC2154
# (silence shellcheck wrt $cam1 environment variable)
if [[ $# -lt 4 ]]; then echo "Format: [narrow=1] [cam1=1] $0 width height framerate ms [us]"; exit; fi
if [[ "$(( $1 % 2 ))" -eq 1 ]]; then echo "width has to be even"; exit; fi
if [[ "$(( $2 % 2 ))" -eq 1 ]]; then echo "height has to be even"; exit; fi
export SHTR=""; if [[ $# -gt 4 ]]; then SHTR="--shutter"; fi
export workaround=""; if [[ "" != "$(grep '=bookworm' /etc/os-release)" ]]; then workaround="--no-raw"; fi
export d=10; if [[ "" != "$(grep "Revision.*: ...17.$" /proc/cpuinfo)" ]]; then if [[ "$cam1" == "" ]]; then d=6; else d=4; fi; fi
for((m=0; m<=5; ++m))
do
if media-ctl -d "/dev/media$m" --set-v4l2 "'imx296 $d-001a':0 [fmt:SBGGR10_1X10/${1}x$2 crop:($(( (1440 - $1) / 2 )),$(( (1088 - $2) / 2 )))/${1}x$2]" >/dev/null; then echo -e "/dev/media$m\n"; break; fi
done
libcamera-hello --list-cameras ;echo
rm -f /dev/shm/tst.pts
if [[ "" != "$(grep "Revision.*: ...17.$" /proc/cpuinfo)" ]]
then
rpicam-vid "$workaround" ${cam1:+--camera 1} --width "$1" --height "$2" --denoise cdn_off --framerate "$3" -t "$4" "$SHTR" "$5" -o /dev/shm/tst${cam1:+1}.mp4 -n ;echo
~/venv/bin/python ~/rpicam-apps/utils/timestamp.py --plot ${narrow:+--narrow} /dev/shm/tst${cam1:+1}.mp4
else
libcamera-vid "$workaround" --width "$1" --height "$2" --denoise cdn_off --framerate "$3" --save-pts /dev/shm/tst.pts -t "$4" "$SHTR" "$5" -o /dev/shm/tst.h264 -n ;echo
rm -f tstamps.csv && ptsanalyze /dev/shm/tst.pts
fi
@Hermann-SW
Copy link
Author

Hermann-SW commented Jan 6, 2024

Pull request got accepted, then I did delete my fork.
So tool with "--narrow" option can be found in official repo:
https://github.com/raspberrypi/rpicam-apps/blob/main/utils/timestamp.py

"--narrow" help text got improved in the process:

pi@raspberrypi5:~ $ ~/venv/bin/python ~/rpicam-apps/utils/timestamp.py -h 
usage: timestamp.py [-h] [--plot] [--narrow] filename

rpicam-apps timestamp analysis tool
...
options:
  -h, --help  show this help message and exit
  --plot      Plot timestamp graph
  --narrow    Narrow the y-axis by hiding outliers
pi@raspberrypi5:~ $ 

 
 
For a 60s duration 688x136@400fps "center of analog clock" recording ...
https://stamm-wilbrandt.de/videos/688x136.400fps_60s.mp4
https://forums.raspberrypi.com/download/file.php?id=64737
 
... with a single frameskip ...

pi@raspberrypi5:~ $ wget 2>/dev/null https://stamm-wilbrandt.de/videos/688x136.400fps_60s.mp4
pi@raspberrypi5:~ $ ~/venv/bin/python ~/rpicam-apps/utils/timestamp.py --plot --narrow 688x136.400fps_60s.mp4
Total: 24092 frames (24091 samples)
Average: 2.489 ms / 401.768 fps
Minimum: 2.475 ms at frame 11943
Maximum: 4.977 ms at frame 14847
Outliers: 0 (100%) 1 (10.0%) 1 (1.0%) 369 (0.1%)

 
...the average line is now in vertical middle:
https://forums.raspberrypi.com/viewtopic.php?p=2175722#p2175722
https://forums.raspberrypi.com/download/file.php?id=64736

@Hermann-SW
Copy link
Author

Hermann-SW commented Jan 19, 2024

The longer Pi5 is up, the more frameskips are likely to happen.
Simple countermeasure:
reboot before final recording

In order to get better timestamp.py analysis with "--narrow" option in case frameskips are likely, I added "narrow" environment variable handling to GScrop:

pi@raspberrypi5:~ $ uptime
 21:11:06 up 4 days, 19:22,  2 users,  load average: 0.60, 0.57, 0.38
pi@raspberrypi5:~ $ 
pi@raspberrypi5:~ $ narrow=1 GScrop 224 96 536 2000
/dev/media2
...
[libx264 @ 0x555666219830] kb/s:607.83

Total: 1054 frames (1053 samples)
Average: 1.870 ms / 534.697 fps
Minimum: 1.861 ms at frame 146
Maximum: 3.737 ms at frame 129
Outliers: 0 (100%) 2 (10.0%) 2 (1.0%) 1022 (0.1%)

@ddbaron
Copy link

ddbaron commented Feb 26, 2024

I'd like to suggest incorporating the detection of the bus used by the camera before calling media-ctl.

I use this command to parse out the definition:
media-ctl -d /dev/media0 --print-dot | grep -o "imx296 [0-9]-001a" | uniq

@Hermann-SW
Copy link
Author

Hermann-SW commented Feb 26, 2024

Hi,
I will receive my 2nd GS camera tomorrow ;-)
Then I can verify and will incorporate your suggestion.
I want to see whether Pi5 can record both cameras @536fps concurrently — have you already tested that?

@ddbaron
Copy link

ddbaron commented Feb 26, 2024

Updated 28/feb/2024: A bit more testing. I have two GS cameras but they're wired in synchronous mode so I needed to hack gscrop to handle it.

@liyangyuan
Copy link

This is a fantastic tool! Thank you.
By the way, I'm not sure if I'm an outlier or not, but I want to provide some information. I've discovered that I need to use d=6. Additionally, the conditional statement for determination of d doesn't seem to work for my Raspberry 5 8GB.
image
image

@Hermann-SW
Copy link
Author

Hermann-SW commented Mar 9, 2024

Latest revision added dual camera handling for Pi5:

pi@raspberrypi5:~ $ GScrop 
Format: [narrow=1] [cam1=1] /usr/local/bin/GScrop width height framerate ms [us]
pi@raspberrypi5:~ $ 

Default is to use camera 0:

pi@raspberrypi5:~ $ narrow=1 GScrop 688 136 402 1000
/dev/media0
...
[libx264 @ 0x5556652764a0] kb/s:1641.32

Total: 383 frames (382 samples)
Average: 2.500 ms / 400.004 fps
Minimum: 2.469 ms at frame 125
Maximum: 9.895 ms at frame 246
Outliers: 1 (100%) 2 (10.0%) 314 (1.0%) 382 (0.1%)
pi@raspberrypi5:~ $

Here camera 1 is used:

pi@raspberrypi5:~ $ cam1=foobar GScrop 688 136 402 1000
/dev/media1
...
[libx264 @ 0x5555dc266710] kb/s:1369.74

Total: 390 frames (389 samples)
Average: 2.474 ms / 404.186 fps
Minimum: 2.468 ms at frame 139
Maximum: 2.481 ms at frame 140
Outliers: 0 (100%) 0 (10.0%) 0 (1.0%) 5 (0.1%)
pi@raspberrypi5:~ $ 

@Hermann-SW
Copy link
Author

Hermann-SW commented Mar 9, 2024

Revision 11 clean again:

pi@raspberrypi5:~ $ shellcheck /usr/local/bin/GScrop 
pi@raspberrypi5:~ $ 

@Hermann-SW
Copy link
Author

Hermann-SW commented Apr 29, 2024

@Hermann-SW
Copy link
Author

GScrop revision 12 errors out on odd width or odd height.
Reason is that recording with those values would error out later anyway:

pi@raspberrypi5:~ $ shellcheck /usr/local/bin/GScrop 
pi@raspberrypi5:~ $ GScrop 689 137 400 2000
width has to be even
pi@raspberrypi5:~ $ GScrop 688 137 400 2000
height has to be even
pi@raspberrypi5:~ $ GScrop 688 136 400 2000
/dev/media3
...
[libx264 @ 0x5555eb9feda0] kb/s:1342.94

Total: 790 frames (789 samples)
Average: 2.489 ms / 401.784 fps
Minimum: 2.480 ms at frame 696
Maximum: 2.498 ms at frame 695
Outliers: 0 (100%) 0 (10.0%) 0 (1.0%) 53 (0.1%)
pi@raspberrypi5:~ $ 

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment