Getting preview of raspberry pi camera working out of container

Dear all,

I am currently working on a project for continously taking pictures on a Raspberry Pi with a Pi Camera v2. Due to the special nature (continously ;)) of the recording, I use the picamera [ https://picamera.readthedocs.io/en/release-1.13/ ] library, which enables the use of this feature. Also, it got the function start_preview(), which should start the same video overlay as it is used for raspistill and raspivid (I presume, description here: https://picamera.readthedocs.io/en/release-1.13/api_camera.html#picamera.PiCamera.start_preview ).

Due to the nature of that project, behaving like a normal camera, I need to have the preview enabled during recording to make for a fitting “Viewfinder”. As this overlay does not seem to be X11, but more hardware-near, I wanted to ask the tricky question on how to containerize / use with balena said application.

Best regards

Nico

PS: Recording/taking pictures with the camera works, its really about the problem of seeing the preview overlay on the HDMI or Composite Video out :slight_smile:

Hi @nmaas87,

Interesting use case, I presume you have a project that captures the pictures continuously. If you invoke the start_preview() function what happens? Are there any errors in your dashboard?

1 Like

I have a Balena project using the same Python PiCamera library.

The most basic thing is make sure to set BOTH the start_x and gpu_mem config vars on your device and/or fleet in the Balena dashboard as documented here: https://www.balena.io/docs/learn/develop/hardware/i2c-and-spi/#raspberry-pi-camera-module

Assuming you’ve done that, I believe the preview IS actually an X window. Check your X logs let us know if there’s anything in there (probably in /var/log). It’s common to see a silent error saying that there’s a bad display name or something like that.

IF you see the “bad display” error then you need to set your DISPLAY var in your Dockerfile. run (cd /tmp/.X11-unix && for x in X*; do echo ":${x#X}"; done) in your container to list all of the X displays. You should see at least one display. For example for “:0” you’ll want ENV DISPLAY=:0 in your Dockerfile.

For reference, here is a similar project. You can see how they configured it. https://github.com/balena-io-projects/balena-rpi-python-picamera

Side note: personally I use PiCamera in conjunction with OpenCV (cv2) and IMUtils (https://github.com/jrosebr1/imutils/tree/master/imutils). I will say that using this gets me MUCH better frame rates since each frame capture spawns its own async thread.

2 Likes

Hi @mbalamat
Hi @Jassky

thanks for helping out :slight_smile:
I tried https://github.com/balena-io-projects/balena-rpi-python-picamera and changed the code to just start it with the start_preview() and set the time.sleep to 20 seconds. Turns out that - if I just balena run --privileged cam, nothing happens. If I then balena exec -it CONTAINER /bin/bash and execute the python script, I see the preview of the camera. So it looks like you need to be in an interactive session to get the video routed out. Any idea on how to circumvent that and make it work “out of the box” / upon boot of balenaOS

PS: I am using the development version of balenaOS and not the version of the balenaCloud, as this machine is gonna be without network access in the end :).

Best regards,

Nico

@nmaas87 @Jassky 's answer is spot on, but just to clarify some things, what happens if you clone the repo https://github.com/balena-io-projects/balena-rpi-python-picamera , do the code changes you mentioned and assuming that you have balena-cli installed, use balena push <your App's name here> ?

Also about the development vs production versions of balenaOS. I would recommend using the development version in conjunction with the livepush feature to get fast development iterations, more info here.
Use ONLY the production version of balenaOS on the devices you want to deploy in the field and NEVER use the development version on them.

1 Like

Perfectly, that worked out.
For somewhat reason, I needed to hardcode the path, seems there was something off - so changing the start from
python demo.py to /usr/local/bin/python /usr/src/app/demo.py did the trick.
Also, this does now work with my real project in a test setup, so awesome.
I’ll be switching over to the prod image now and test it again, trying to disable as much of the resin-supervisor and node applications in the process, as I mostly deploy these more “handcrafted” and later isolated systems by manual means - and want to free up as much resources as possible (sorry for being quite a barbarian… ^^’)
Thanks a lot for the swift help, this worked easier than thought, I’ll probably have a look at the composite out soon, but as hdmi works now, this should work after playing around a bit with the config.txt and soldering on some headers to actually attach something to the video out :slight_smile:

Best regards

Nico

1 Like