0

I am trying to write my own motion detection camera Python program for my Raspberry Pi for recording video when motion is detected. I have the following code using Python Picamera2:

#!/usr/bin/python3
import time, os
from datetime import datetime

import numpy as np

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

time_format = "%Y-%m-%d-%H-%M-%S"
frame_rate = 30

lsize = (320, 240)
picam2 = Picamera2()
video_config = picam2.create_video_configuration(main={"size": (1920, 1080), "format": "RGB888"}, lores={
                                                 "size": lsize, "format": "YUV420"})
picam2.configure(video_config)
picam2.start_preview()
encoder = H264Encoder(2000000, repeat=True)
encoder.output = CircularOutput()
picam2.encoder = encoder
picam2.start()
picam2.start_encoder()

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

while True:
    cur = picam2.capture_buffer("lores")
    cur = cur[:w * h].reshape(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:
                filename = datetime.now().strftime(time_format)
                encoder.output.fileoutput = f"{filename}.h264"
                encoder.output.start()
                encoding = True
                print("New Motion", mse)
            ltime = time.time()
        else:
            if encoding and time.time() - ltime > 5.0:
                encoder.output.stop()
                encoding = False
                time.sleep(1)
                os.system(f"ffmpeg -r {frame_rate} -i {filename}.h264 -vcodec copy {filename}.mp4")
                os.system(f"rm {filename}.h264")
    prev = cur

picam2.stop_encoder()

This does appear to work okay. I had to add the os.system ffmpeg command to convert the video to mp4 so I could actually view the video on my Windows 10 PC.

There are a couple of issues with this:

  1. I would like to reduce the frame rate to around 15 FPS as the default 30 FPS is not required.
  2. The focus in the image is not on the centre of the image, but on a shelf that is closer and makes the image very blurry. How can I make it focus on the centre of the image?
  3. Can I have the encoder output as mp4 or mkv without having to use ffmpeg to convert?

My Raspberry Pi 4 4GB has 22-09-2022 Bullseye OS and is fully up to date. My camera is the new Pi Camera 3 Module.

4
  • 1
    This is NOT a free coding forum and your question have several questions.
    – MatsK
    Jan 19, 2023 at 16:26
  • "Raspberry Pi Stack Exchange is a question and answer site for users and developers of hardware and software for Raspberry Pi."
    – atl-it
    Jan 21, 2023 at 5:22
  • 1
    And when you are reading the rules, please read about "How to ask questions" as well.
    – MatsK
    Jan 22, 2023 at 18:12
  • It is great that you have found an answer to some of the issues that you were experiencing. However, as you have provided an answer to issues one and two, and accepted that answer, now there is no reason for anyone to provide an answer to issue three. Or... if someone does provide an answer to issue three, you will not be able to accept that answer as well. That is why you can not ask multiple questions in one question post. I suggest that you edit your question and delete issue three and post it as a separate question. Jan 24, 2023 at 11:45

1 Answer 1

0

For anyone interested or with the same issue, I have the answers to questions 1 and 2. I added the following lines to my code - the import at the top:

from libcamera import controls

and the picam2 lines before picam2.start()

picam2.set_controls({"FrameRate": frame_rate})
picam2.set_controls({"AfMode": controls.AfModeEnum.Continuous})

It doesn't refocus on the centre of the image, but the focus is much improved so I am happy. There is a control called AfWindows to allow focusing on a portion of the image, but at the time of this question it does not work with the current release of Picamera2. Question number 3 is, to my knowledge, not possible when using CircularOutput, so the solution is to convert to mp4 afterwards (this is included in the code in the question). Alles ist gut :-)

1

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.