Getting overlay to work while recording

A project log for Raspberry Pi Zero FPV camera and OSD

Pi Zero and camera weigh 13 grams making it an ideal setup for data logging, HD video recording and custom On Screen Display for FPV.

Maksim SurguyMaksim Surguy 07/14/2016 at 16:301 Comment

I have researched various ways to achieve basic requirements such as having a preview with On Screen Display (OSD) that is streamed through FPV transmitter and recording unmodified video at the same time.

From my research I found a few ways of overlaying text and additional information while using the Raspberry Pi camera:

- By using UV4L library ( and chrome-extension://klbibkeccnjlkjkiokjodocebajanakg/suspended.html#uri=

- By using OpenGL libraries, some of which are outdated and are hard to get started with

- By using PiCamera Python library and its feature of overlaying an arbitrary array of pixels in Preview mode (

I settled on the third option as it is easy to program and has great documentation. I then searched Github for existing projects that use the preview overlay feature in PiCamera and found a single example that pointed me in the right direction. PiCamera library allows overlaying an array of pixels which means you can either create your own drawing library to create that array or use existing Python libraries that will do that for you based on your requirements. The project at uses Image and ImageDraw Python libraries to create a great looking HUD. Another example in the same project had a basic implementation that proved to be useful for my FPV OSD project.

Based on that find, here's the code I wrote that displays a crosshair and current timestamps in multiple positions on the preview screen while recording unmodified HD video:

import picamera
import time
import numpy
from PIL import Image, ImageDraw, ImageFont

# Video Resolution

# Cross Hair Image
crossHairPixels = crossHair.load()
for x in range (0, VIDEO_WIDTH):
   crossHairPixels[x, 360] = (255, 255, 0)

for x in range(0, VIDEO_HEIGHT):
   crossHairPixels[640, x] = (255, 255, 0)

with picamera.PiCamera() as camera:
   camera.resolution = (VIDEO_WIDTH, VIDEO_HEIGHT)
   camera.framerate = 30
   camera.led = False

   img = crossHair.copy()
   overlay = camera.add_overlay(img.tostring(), layer = 3, alpha = 100) 

      while True:
         text = time.strftime('%H:%M:%S', time.gmtime())
         img = crossHair.copy()
         draw = ImageDraw.Draw(img)
         draw.font = ImageFont.truetype("/usr/share/fonts/truetype/freefont/FreeSerif.ttf", 20)
         draw.text((10, 10), text, (255, 255, 255))
         draw.text((10, 100), text, (0, 255, 255))
         draw.text((10, 200), text, (255, 0, 255))
         draw.text((10, 300), text, (255, 255, 0))
         draw.text((200, 10), text, (255, 255, 255))
         draw.text((300, 100), text, (0, 255, 255))
         draw.text((400, 200), text, (255, 0, 255))
         draw.text((500, 300), text, (255, 255, 0))


I have tested this code on the Pi Zero and was able to get consistent 30FPS recording while overlaying the text in multiple places on the preview screen. The CPU load was at about 23% because the overlay is updated once a second or so.

Now with this basic functionality working I can get to plugging in the sensors and reading the data from the flight controller that has serial interface.

My next steps are:

- Get GPS data and display it on the screen

- Get positional/rotational data from the Flight controller and display it on the preview screen

- Get battery status and display it on the screen


peter.valencic wrote 10/11/2017 at 20:51 point

Is those text also embeded in timestamped.h264? I need the same functionality.. What I want is to save a video stream with embedded text on different x,y position.. 

  Are you sure? yes | no