Skip to content

Commit

Permalink
Merge branch 'main' into dma_example
Browse files Browse the repository at this point in the history
  • Loading branch information
kodonnell committed Jan 27, 2025
2 parents 910132d + bbd730d commit ee44f64
Show file tree
Hide file tree
Showing 71 changed files with 6,455 additions and 138 deletions.
6 changes: 3 additions & 3 deletions .github/workflows/flake8.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ jobs:
- name: Set up Python 3.9
uses: actions/setup-python@v4
with:
python-version: '3.9.13'
python-version: '3.9.19'
- name: Update
run: sudo apt update
- name: Install apt dependencies
Expand All @@ -32,7 +32,7 @@ jobs:
key: ${{ runner.os }}-libcamera2-${{env.LIBCAMERA-HASH}}
- name: Generate libcamera
if: steps.cache-libcamera.outputs.cache-hit != 'true'
run: cd /home/runner/work; git clone https://github.com/raspberrypi/libcamera.git; cd libcamera; meson build --buildtype=release -Dpipelines=rpi/vc4 -Dipas=rpi/vc4 -Dv4l2=true -Dtest=false -Dlc-compliance=disabled -Dcam=disabled -Dqcam=enabled -Dpycamera=enabled -Ddocumentation=disabled ; ninja -C build
run: cd /home/runner/work; git clone https://github.com/raspberrypi/libcamera.git; cd libcamera; meson build --buildtype=release -Dpipelines=rpi/vc4 -Dipas=rpi/vc4 -Dv4l2=true -Dtest=false -Dlc-compliance=disabled -Dcam=disabled -Dqcam=disabled -Dpycamera=enabled -Ddocumentation=disabled ; ninja -C build
lint:
name: lint code
needs: compile
Expand All @@ -42,7 +42,7 @@ jobs:
- name: Set up Python 3.9
uses: actions/setup-python@v4
with:
python-version: '3.9.13'
python-version: '3.9.19'
- name: Display python version
run: python -c "import sys; print(sys.version)"
- name: Update
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/run_tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,5 +20,5 @@ jobs:
clean: true

- name: Test
run: DISPLAY=:0 PYTHONPATH=/home/pi/_work/picamera2/picamera2:/home/pi/libcamera/build/src/py:/home/pi/kmsxx/build/py:/home/pi/python-v4l2 python3 ${{github.workspace}}/tools/run_tests.py -p ${{github.workspace}}
run: DISPLAY=:0 ASSET_DIR=/home/pi/assets PYTHONPATH=/home/pi/_work/picamera2/picamera2:/home/pi/libcamera/build/src/py:/home/pi/kmsxx/build/py:/home/pi/python-v4l2 python3 ${{github.workspace}}/tools/run_tests.py -p ${{github.workspace}}
timeout-minutes: 30
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -51,3 +51,4 @@ docs/_build/
.idea
/.spyproject
.spyproject
hailort.log
69 changes: 69 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,75 @@

### Changed

## 0.3.24 Beta Release 23

### Added

* FfmpegOutput support custom audio filter

### Changed

* Updated for newer version of PyAV which we can use to encode
more efficiently.

## 0.3.23 Beta Release 22

### Added

* rpi::ScalerCrops control support
* Hailo multi-model support
* Stereo preview example script
* Add PyavOutput and a new CircularOutput2
* Allow libav H264 encoder to use V4L2 hardware on VC4 platforms
* bbox-order argument for imx500_object_detection_demo script

### Changed

* Fix ScalerCrops tests
* imx500: Update MAX_NUM_TENSORS and MAX_NUM_DIMENSIONS
* Fix V4L2 encoder not releasing requests

## 0.3.22 Beta Release 21

### Changed

* Add to_tuple methods to libcamera Rectangle and Size types
* Add IMX500 support

## 0.3.21 Beta Release 20

### Changed

* Fixed setup.py for the devices helpers
* Fixed handling of the ScalerCrops control in app_full.py

## 0.3.20 Beta Release 19

### Added

* Initial support for Hailo AI devices, including some examples.
* IMX708 helper class so that the sensor HDR mode can be set with Python.

### Changed

* Improved handling of timeouts when cameras stop responding, including a mechanism for a complete
reset if requests stop being returned.
* Platform checking more robust.
* Add missing flush parameter to captured_request() (for use with context manager).

## 0.3.19 Beta Release 18

### Added

* Add an example showing how to forward images to other processes using zero-copy.
* Add a context manager method for capturing requests, e.g. `with picam2.captured_request() as r:`
* Encoders can skip frames, e.g. run at half the rate of the camera.

### Changed

* Configuration alignment fixed on Pi 5.
* Improve support for displays without alpha blending.

## 0.3.18 Beta Release 17

### Added
Expand Down
47 changes: 7 additions & 40 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,58 +12,25 @@ There are also many examples in the `examples` folder of this repository, and so

## Installation

_Picamera2_ is only supported on Raspberry Pi OS Bullseye (or later) images, both 32 and 64-bit. As of September 2022, _Picamera2_ is pre-installed on images downloaded from Raspberry Pi. It works on all Raspberry Pi boards right down to the Pi Zero, although performance in some areas may be worse on less powerful devices.
_Picamera2_ is only supported on Raspberry Pi OS Bullseye (or later) images, both 32 and 64-bit. As of September 2022, _Picamera2_ is pre-installed on Raspberry Pi OS images, but not on Raspberry Pi OS Lite images. It works on all Raspberry Pi boards right down to the Pi Zero, although performance in some areas may be worse on less powerful devices.

_Picamera2_ is _not_ supported on:

* Images based on Buster or earlier releases.
* Raspberry Pi OS Legacy images.
* Bullseye (or later) images where the legacy camera stack has been re-enabled.

On Raspberry Pi OS images, _Picamera2_ is now installed with all the GUI (_Qt_ and _OpenGL_) dependencies. On Raspberry Pi OS Lite, it is installed without the GUI dependencies, although preview images can still be displayed using DRM/KMS. If these users wish to use the additional X-Windows GUI features, they will need to run
On systems where _Picamera2_ is supported but not pre-installed, you can install it with
```
sudo apt install -y python3-pyqt5 python3-opengl
sudo apt install python3-picamera2 --no-install-recommends
```
(No changes are required to _Picamera2_ itself.)

### Installation using `apt`

`apt` is the recommended way of installing and updating _Picamera2_.

If _Picamera2_ is already installed, you can update it with `sudo apt install -y python3-picamera2`, or as part of a full system update (for example, `sudo apt upgrade`).

If _Picamera2_ is not already installed, then your image is presumably older and you should start with
```
sudo apt update
sudo apt upgrade
```
If you have installed _Picamera2_ previously using `pip`, then you should also uninstall this (`pip3 uninstall picamera2`).

Thereafter, you can install _Picamera2_ _with_ all the GUI (_Qt_ and _OpenGL_) dependencies using
to get a slightly reduced installation with fewer of the window system related elements (this would be suitable for installing on a Raspberry Pi OS Lite system), or
```
sudo apt install -y python3-picamera2
```
If you do _not_ want the GUI dependencies, use
```
sudo apt install -y python3-picamera2 --no-install-recommends
sudo apt install python3-picamera2
```
for a full installation.

### Installation using `pip`

This is no longer the recommended way to install _Picamera2_. However, if you want to do so you can use
```
sudo apt install -y python3-libcamera python3-kms++
sudo apt install -y python3-pyqt5 python3-prctl libatlas-base-dev ffmpeg python3-pip
pip3 install numpy --upgrade
pip3 install picamera2[gui]
```
which will install _Picamera2_ with all the GUI (_Qt_ and _OpenGL_) dependencies. If you do not want these, please use
```
sudo apt install -y python3-libcamera python3-kms++
sudo apt install -y python3-prctl libatlas-base-dev ffmpeg libopenjp2-7 python3-pip
pip3 install numpy --upgrade
pip3 install picamera2
```
_Picamera2_ can be installed using `pip`, however, we recommend installing through `apt` as this guarantees you will get versions of _Picamera2_ and the underlying _libcamera_ libraries that have been confirmed as working together.

## Contributing

Expand Down
1 change: 1 addition & 0 deletions apps/app_full.py
Original file line number Diff line number Diff line change
Expand Up @@ -1180,6 +1180,7 @@ def toggle_hidden_controls():
"AfWindows",
"AfPause",
"AfMetering",
"ScalerCrops"
}

# Main widgets
Expand Down
26 changes: 26 additions & 0 deletions examples/ffmpeg_audio_filter.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
#!/usr/bin/python3
import time

from picamera2 import Picamera2
from picamera2.encoders import H264Encoder
from picamera2.outputs import FfmpegOutput

picam2 = Picamera2()
video_config = picam2.create_video_configuration()
picam2.configure(video_config)
encoder = H264Encoder(10000000)

# audio filter takes the left channel and copies it to the right channel
# below example copies c0 (left channel) to c1 (right channel) - convert mono to stereo

# or add audio delay on left channel like this: audio_filter="pan=stereo|adelay=1500|0"
# source for more examples: https://ffmpeg.org/ffmpeg-filters.html#Examples-2
output = FfmpegOutput(
'ffmpeg_audio_filter_test.mp4',
audio=True,
audio_filter="pan=stereo|c0=c0|c1=c0"
)

picam2.start_recording(encoder, output)
time.sleep(10)
picam2.stop_recording()
80 changes: 80 additions & 0 deletions examples/hailo/coco.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
person
bicycle
car
motorcycle
airplane
bus
train
truck
boat
traffic light
fire hydrant
stop sign
parking meter
bench
bird
cat
dog
horse
sheep
cow
elephant
bear
zebra
giraffe
backpack
umbrella
handbag
tie
suitcase
frisbee
skis
snowboard
sports ball
kite
baseball bat
baseball glove
skateboard
surfboard
tennis racket
bottle
wine glass
cup
fork
knife
spoon
bowl
banana
apple
sandwich
orange
broccoli
carrot
hot dog
pizza
donut
cake
chair
couch
potted plant
bed
dining table
toilet
tv
laptop
mouse
remote
keyboard
cell phone
microwave
oven
toaster
sink
refrigerator
book
clock
vase
scissors
teddy bear
hair drier
toothbrush
81 changes: 81 additions & 0 deletions examples/hailo/detect.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
#!/usr/bin/env python3

"""Example module for Hailo Detection."""

import argparse

import cv2

from picamera2 import MappedArray, Picamera2, Preview
from picamera2.devices import Hailo


def extract_detections(hailo_output, w, h, class_names, threshold=0.5):
"""Extract detections from the HailoRT-postprocess output."""
results = []
for class_id, detections in enumerate(hailo_output):
for detection in detections:
score = detection[4]
if score >= threshold:
y0, x0, y1, x1 = detection[:4]
bbox = (int(x0 * w), int(y0 * h), int(x1 * w), int(y1 * h))
results.append([class_names[class_id], bbox, score])
return results


def draw_objects(request):
current_detections = detections
if current_detections:
with MappedArray(request, "main") as m:
for class_name, bbox, score in current_detections:
x0, y0, x1, y1 = bbox
label = f"{class_name} %{int(score * 100)}"
cv2.rectangle(m.array, (x0, y0), (x1, y1), (0, 255, 0, 0), 2)
cv2.putText(m.array, label, (x0 + 5, y0 + 15),
cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 255, 0, 0), 1, cv2.LINE_AA)


if __name__ == "__main__":
# Parse command-line arguments.
parser = argparse.ArgumentParser(description="Detection Example")
parser.add_argument("-m", "--model", help="Path for the HEF model.",
default="/usr/share/hailo-models/yolov8s_h8l.hef")
parser.add_argument("-l", "--labels", default="coco.txt",
help="Path to a text file containing labels.")
parser.add_argument("-s", "--score_thresh", type=float, default=0.5,
help="Score threshold, must be a float between 0 and 1.")
args = parser.parse_args()

# Get the Hailo model, the input size it wants, and the size of our preview stream.
with Hailo(args.model) as hailo:
model_h, model_w, _ = hailo.get_input_shape()
video_w, video_h = 1280, 960

# Load class names from the labels file
with open(args.labels, 'r', encoding="utf-8") as f:
class_names = f.read().splitlines()

# The list of detected objects to draw.
detections = None

# Configure and start Picamera2.
with Picamera2() as picam2:
main = {'size': (video_w, video_h), 'format': 'XRGB8888'}
lores = {'size': (model_w, model_h), 'format': 'RGB888'}
controls = {'FrameRate': 30}
config = picam2.create_preview_configuration(main, lores=lores, controls=controls)
picam2.configure(config)

picam2.start_preview(Preview.QTGL, x=0, y=0, width=video_w, height=video_h)
picam2.start()
picam2.pre_callback = draw_objects

# Process each low resolution camera frame.
while True:
frame = picam2.capture_array('lores')

# Run inference on the preprocessed frame
results = hailo.run(frame)

# Extract detections from the inference results
detections = extract_detections(results, video_w, video_h, class_names, args.score_thresh)
Loading

0 comments on commit ee44f64

Please sign in to comment.