Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 12 additions & 8 deletions examples/capture_average.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,12 @@
import numpy as np
from PIL import Image

from picamera2 import Picamera2, Preview
from picamera2 import MappedArray, Picamera2, Preview

picam2 = Picamera2()
picam2.start_preview(Preview.NULL)
capture_config = picam2.create_still_configuration()
# Buffer count of 2 will reduce frame drops (default is 1 otherwise)
capture_config = picam2.create_still_configuration(buffer_count=2)
picam2.configure(capture_config)

picam2.start()
Expand All @@ -25,12 +26,15 @@
imgs = 20 # Capture 20 images to average
sumv = None
for _ in range(imgs):
if sumv is None:
sumv = np.longdouble(picam2.capture_array())
img = Image.fromarray(np.uint8(sumv))
img.save("original.tif")
else:
sumv += np.longdouble(picam2.capture_array())
with picam2.captured_request() as request:
# Using MappedArray saves an array copy
with MappedArray(request, 'main') as m:
if sumv is None:
sumv = np.longdouble(m.array)
img = Image.fromarray(np.uint8(m.array))
img.save("original.tif")
else:
sumv += m.array

img = Image.fromarray(np.uint8(sumv / imgs))
img.save("averaged.tif")
2 changes: 2 additions & 0 deletions examples/capture_dng_to_buffer.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
#!/usr/bin/python3

# Capture a DNG to a BytesIO.

import io
import time

Expand Down
5 changes: 5 additions & 0 deletions examples/capture_mjpeg.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,11 @@
from picamera2 import Picamera2
from picamera2.encoders import JpegEncoder

# This is using the software JPEG encoder. On lower powered devices, the
# MJPEGEncoder would be better as it uses the hardware encoder. See
# capture_mjpeg_v4l2.py.


picam2 = Picamera2()
video_config = picam2.create_video_configuration(main={"size": (1920, 1080)})
picam2.configure(video_config)
Expand Down
5 changes: 5 additions & 0 deletions examples/capture_mjpeg_timestamp.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,11 @@
from picamera2 import Picamera2
from picamera2.encoders import JpegEncoder

# This is using the software JPEG encoder. On lower powered devices, the
# MJPEGEncoder would be better as it uses the hardware encoder. See
# capture_mjpeg_v4l2.py.


picam2 = Picamera2()
video_config = picam2.create_video_configuration(main={"size": (1920, 1080)})
picam2.configure(video_config)
Expand Down
4 changes: 4 additions & 0 deletions examples/capture_motion.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
#!/usr/bin/python3

# This example writes unformatted H.264 bitstream using the FileOutput. Mostly
# we would now recommend using the PyavOutput to write mp4 files directly. See
# capture_motion_improved.py.

import time

import numpy as np
Expand Down
42 changes: 42 additions & 0 deletions examples/capture_motion_improved.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
#!/usr/bin/python3

import time

import numpy as np

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

lsize = (320, 240)
picam2 = Picamera2()
main = {"size": (1280, 720), "format": "RGB888"}
lores = {"size": lsize, "format": "YUV420"}
video_config = picam2.create_video_configuration(main, lores=lores)
picam2.configure(video_config)
encoder = H264Encoder(bitrate=1000000)
picam2.start()

w, h = lsize
prev = None
encoding = False
ltime = 0

while True:
cur = picam2.capture_array("lores")[:h, :w]
if prev is not None:
# Measure pixels differences between current and
# previous frame
mse = np.square(np.subtract(cur, prev)).mean()
if mse > 7:
if not encoding:
encoder.output = PyavOutput(f"{int(time.time())}.mp4")
picam2.start_encoder(encoder)
encoding = True
print("New Motion", mse)
ltime = time.time()
else:
if encoding and time.time() - ltime > 2.0:
picam2.stop_encoder()
encoding = False
prev = cur
4 changes: 4 additions & 0 deletions examples/capture_stream_udp.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
#!/usr/bin/python3

# Send an H.264 bitstream over a UDP socket to a client. Mostly we would
# recommend using PyavOutput so that you can send more widely supported
# formats. See capture_stream_udp_improved.py.

import socket
import time

Expand Down
21 changes: 21 additions & 0 deletions examples/capture_stream_udp_improved.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
#!/usr/bin/python3

# Send an MPEG2 transport stream over a socket using PyavOutput.

import socket
import time

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

picam2 = Picamera2()
video_config = picam2.create_video_configuration({"size": (1280, 720)})
picam2.configure(video_config)
encoder = H264Encoder(1000000)

with socket.socket(socket.AF_INET, socket.SOCK_DGRAM) as sock:
sock.connect(("REMOTEIP", 10001))
picam2.start_recording(encoder, PyavOutput(f"pipe:{sock.fileno()}", format="mpegts")) # noqa
time.sleep(20)
picam2.stop_recording()
4 changes: 4 additions & 0 deletions examples/capture_video.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@
from picamera2 import Picamera2
from picamera2.encoders import H264Encoder

# This example saves an unformatted H.264 file. Mostly we would recommend
# using the PyavOutput so that an mp4 file could be saved directly instead.


picam2 = Picamera2()
video_config = picam2.create_video_configuration()
picam2.configure(video_config)
Expand Down
4 changes: 4 additions & 0 deletions examples/easy_capture.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
#!/usr/bin/python3

# This is the most high level way to capture images and save them. Howwever,
# the API gives you less control over the camera system so we would recommend
# it only to folks with the simplest use-cases.

from picamera2 import Picamera2

picam2 = Picamera2()
Expand Down
4 changes: 4 additions & 0 deletions examples/easy_video.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
#!/usr/bin/python3

# This is the most high level way to capture and save a video. Howwever,
# the API gives you less control over the camera system so we would recommend
# it only to folks with the simplest use-cases.

from picamera2 import Picamera2

picam2 = Picamera2()
Expand Down
8 changes: 4 additions & 4 deletions examples/metadata_with_image.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,10 @@
picam2.start()
time.sleep(2)

request = picam2.capture_request()
image = request.make_image("main") # image from the "main" stream
metadata = request.get_metadata()
request.release() # requests must always be returned to libcamera
# THe "with" block will release the request when it exits
with picam2.captured_request() as request:
image = request.make_image("main") # image from the "main" stream
metadata = request.get_metadata()

image.show()
print(metadata)
3 changes: 3 additions & 0 deletions examples/mjpeg_server.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@
# Run this script, then point a web browser at http:<this-ip-address>:8000
# Note: needs simplejpeg to be installed (pip3 install simplejpeg).

# This version uses the software JPEG encoder, so on Pi 4 or earlier devices,
# mjpeg_server_2.py, which will use the hardware encoder, is probably better.

import io
import logging
import socketserver
Expand Down
8 changes: 4 additions & 4 deletions examples/still_during_video.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,15 +14,15 @@
video_config = picam2.create_video_configuration(main_stream, lores_stream, encode="lores")
picam2.configure(video_config)

encoder = H264Encoder(10000000)
encoder = H264Encoder(bitrate=10000000)

picam2.start_recording(encoder, 'test.h264')
time.sleep(5)

# It's better to capture the still in this thread, not in the one driving the camera.
request = picam2.capture_request()
request.save("main", "test.jpg")
request.release()
# The "with" block will release the request automatically when it exits.
with picam2.captured_request() as request:
request.save("main", "test.jpg")
print("Still image captured!")

time.sleep(5)
Expand Down
30 changes: 20 additions & 10 deletions picamera2/picamera2.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@
import picamera2.utils as utils
from picamera2.allocators import DmaAllocator
from picamera2.encoders import Encoder, H264Encoder, MJPEGEncoder, Quality
from picamera2.outputs import FfmpegOutput, FileOutput
from picamera2.outputs import FileOutput, PyavOutput
from picamera2.previews import DrmPreview, NullPreview, QtGlPreview, QtPreview

from .configuration import CameraConfiguration
Expand Down Expand Up @@ -2596,26 +2596,36 @@ def start_and_record_video(self, output, encoder=None, config=None, quality=Qual
example by calling stop_recording).

audio - whether to record audio. This is only effective when recording to an "mp4" or "ts"
file, and there is a microphone installed and working as the default input device
through Pulseaudio.
file, and there is a microphone installed and working as the default input device.
"""
if self.started:
self.stop()
if not self.camera_config and config is None:
config = "video"
if config is not None:
self.configure(config)

if isinstance(output, str):
if encoder is None:
extension = output.split('.')[-1].lower()
if extension in ("mjpg", "mjpeg"):
extension = output.split('.')[-1].lower()
if extension in ("mjpg", "mjpeg"):
if audio:
raise ValueError("Audio not supported in MJPEG flies")
if encoder is None:
encoder = MJPEGEncoder()
if extension in ("mp4", "ts"):
output = FfmpegOutput(output, audio=audio)
else:
output = FileOutput(output)
output = PyavOutput(output)
elif extension in ("mp4", "ts"):
if encoder is None:
encoder = H264Encoder()
output = PyavOutput(output)
else:
if audio:
raise ValueError("Audio not supported in output " + output)
output = FileOutput(output)

if encoder is None:
encoder = H264Encoder()
encoder.audio = audio

self.start_encoder(encoder=encoder, output=output, quality=quality)
self.start(show_preview=show_preview)
if duration:
Expand Down