waveform80 / picamera

A pure Python interface to the Raspberry Pi camera module
https://picamera.readthedocs.io/
BSD 3-Clause "New" or "Revised" License
1.57k stars 355 forks source link

Camera Overlay not Owned Instance #591

Closed ReadieS closed 5 years ago

ReadieS commented 5 years ago

Please forgive me if this is a totally NOOB Question. This is my first attempt at python coding and I have tried asking for help in other groups but no one has come back to me. I have been attempting to create a fairly simple script that I will load on boot of a Pi, I will open a preview window without any input and it will stay there until the pi is turned off. I then want a button which will start and stop video recording for which I have used gpiozero. This all works fine but then I started trying to use a pil overlay to show when the video is recording. my code loads the overlay perfectly but when I try to remove the overlay it throws the error:

File "/usr/lib/python3/dist-packages/picamera/camera.py", line 908, in remove_overlay
"The specified overlay is not owned by this instance of "
picamera.exc.PiCameraValueError: The specified overlay is not owned by this instance of PiCamera

I have tried researching this on my own but being a learner to python I haven't found anything to help me interpret it clearly.

I would be very grateful if someone could give me a pointer in the right direction.

My current code is below, I have pieced it together from various examples along with my very limited knowledge:
from gpiozero import Button
from picamera import PiCamera
from datetime import datetime
from signal import pause
from PIL import Image
import time

button = Button(2)
camera = PiCamera()
camera.resolution = (1024, 768)
camera.start_preview(fullscreen=True)

#define sams variables
recording = 0

def startstop():
    global recording
    overlay1=0

    if recording==0:
        recording=1
        filename = "video-%s.h264" % time.strftime("%d%m%Y-%H%M%S", time.localtime())
        camera.start_recording(filename)
        camera.wait_recording(1)
        # Load the arbitrarily sized image
        img = Image.open('record.png')
        # Create an image padded to the required size with
        # mode 'RGB'
        pad = Image.new('RGB', (
            ((img.size[0] + 31) // 32) * 32,
            ((img.size[1] + 15) // 16) * 16,
            ))
        # Paste the original image into the padded one
        pad.paste(img, (0, 0))

        # Add the overlay with the padded image as the source,
        # but the original image's dimensions
        overlay1 = camera.add_overlay(pad.tobytes(), size=img.size)
        # By default, the overlay is in layer 0, beneath the
        # preview (which defaults to layer 2). Here we make
        # the new overlay semi-transparent, then move it above
        # the preview
        overlay1.alpha = 128
        overlay1.layer = 3

    else:
        camera.remove_overlay(overlay1)
        camera.stop_recording()
        recording=0
        time.sleep(1)

button.when_pressed = startstop

Thanks

ReadieS commented 5 years ago

So I am thinking I have been too focused on on gpiozero. after a bit of digging a research after finding this post I think I need to be using a while loop and polling the gpio pins for a low signal when it is connected to earth in-order to change recording states and add and remove overlays.

I'm thinking the error with my above code has something to do with me calling the function twice, once to start and once to stop. I had put in the overlay1=0to avoid an undeclared variable but i think this should have hinted to me that code wasn't calling on the correct thing. I still dont totally understand it. Like I said its my first time using Python (not sure I can really say "coding in" as most of it is copied and pasted from examples!)

I'm going to go ahead and close the issue and stick it down to my ineptness at python. Thanks,