Don't forget to delete the hdmi_out and hdmi_in when finished

Text Overlay Filter Example

In this notebook, we will demonstrate how to use the overlay filter. The overlay filter scrolls text across the video stream. The text, size and color can be controlled in the Jupiter notebook. In order to do this we take advantage of many writable registers in the pynq.

This filter has a font stored in BRAM. The filter grabs the characters needed based on the ascii codes given. Once retrieved the font’s size and color can be changed. These are controlled by registers. A counter is then used to change the Text location as it moves across the screen. The speed of the scroll is based on a register.

1. Download base overlay to the board

Ensure that the camera is not connected to the board. Run the following script to provide the PYNQ with its base overlay.


In [1]:
from pynq.drivers.video import HDMI
from pynq import Bitstream_Part
from pynq.board import Register
from pynq import Overlay

Overlay("demo.bit").download()

2. Connect camera

Physically connect the camera to the HDMI-in port of the PYNQ. Run the following code to instruct the PYNQ to capture the video from the camera and to begin streaming video to your monitor (connected to the HDMI-out port).


In [2]:
hdmi_in = HDMI('in')
hdmi_out = HDMI('out', frame_list=hdmi_in.frame_list)
hdmi_out.mode(2)
hdmi_out.start()
hdmi_in.start()

3. Program the board and User interface

For this filter we use the user interface to program the board. The interface will be explain below. Run the follow script to start the interface.


In [4]:
import ipywidgets as widgets
R0 =Register(0)
R1 =Register(1)
R2 =Register(2)
R3 =Register(3)
R4 =Register(4)
R5 =Register(5)
R6 =Register(6)
R7 =Register(7)
R8 =Register(8)
R9 =Register(9)
R10 =Register(10)
R11 =Register(11)
R12 =Register(12)
R13 =Register(13)
R14 =Register(14)
R15 =Register(15)
R16 =Register(16)
R17 =Register(17)
R18 =Register(18)
R19 =Register(19)
R20 =Register(20)
R21 =Register(21)
R22 =Register(22)
R23 =Register(23)
R24 =Register(24)


R0.write(0)
R1.write(150)
R2.write(1150)
R3.write(32)
R4.write(0)
R5.write(0)
R6.write(0)
R7.write(0)
R8.write(1)

R0_s = widgets.IntSlider(
    value=0,
    min=0,
    max=1000,
    step=1,
    description='Y axis',
    disabled=False,
    continuous_update=True,
    orientation='vertical',
    readout=True,
    readout_format='i',
    slider_color='black'
)
R1_s = widgets.IntSlider(
    value=150,
    min=130,
    max=400,
    step=1,
    description='Left Limit',
    disabled=False,
    continuous_update=True,
    orientation='vertical',
    readout=True,
    readout_format='i',
    slider_color='black'
)
R2_s = widgets.IntSlider(
    value=1150,
    min=500,
    max=1200,
    step=1,
    description='Right Limit',
    disabled=False,
    continuous_update=True,
    orientation='vertical',
    readout=True,
    readout_format='i',
    slider_color='black'
)
R3_s = widgets.IntSlider(
    value=32,
    min=0,
    max=64,
    step=1,
    description='# Chars',
    disabled=False,
    continuous_update=True,
    orientation='vertical',
    readout=True,
    readout_format='i',
    slider_color='black'
)

R4_s = widgets.IntSlider(
    value=1,
    min=0,
    max=4,
    step=1,
    description='Text size',
    disabled=False,
    continuous_update=True,
    orientation='vertical',
    readout=True,
    readout_format='i',
    slider_color='black'
)

R5_s = widgets.IntSlider(
    value=0,
    min=0,
    max=255,
    step=1,
    description='Red',
    disabled=False,
    continuous_update=True,
    orientation='vertical',
    readout=True,
    readout_format='i',
    slider_color='red'
)

R6_s = widgets.IntSlider(
    value=0,
    min=0,
    max=255,
    step=1,
    description='Green',
    disabled=False,
    continuous_update=True,
    orientation='vertical',
    readout=True,
    readout_format='i',
    slider_color='green'
)

R7_s = widgets.IntSlider(
    value=0,
    min=0,
    max=255,
    step=1,
    description='Blue',
    disabled=False,
    continuous_update=True,
    orientation='vertical',
    readout=True,
    readout_format='i',
    slider_color='blue'
)

R8_s = widgets.IntSlider(
    value=1,
    min=1,
    max=3,
    step=1,
    description='Speed',
    disabled=False,
    continuous_update=True,
    orientation='vertical',
    readout=True,
    readout_format='i',
    slider_color='black'
)

R9_s = widgets.Textarea(
    value='Hello World',
    placeholder='Type something',
    description='Text:',
    disabled=False
)

def update_r0(*args):
    R0.write(R0_s.value)
R0_s.observe(update_r0, 'value')
def update_r1(*args):
    R1.write(R1_s.value)
R1_s.observe(update_r1, 'value')
def update_r2(*args):
    R2.write(R2_s.value)
R2_s.observe(update_r2, 'value')
def update_r3(*args):
    R3.write(R3_s.value)
R3_s.observe(update_r3, 'value')
def update_r4(*args):
    R4.write(R4_s.value)
R4_s.observe(update_r4, 'value')
def update_r5(*args):
    R5.write(R5_s.value)
R5_s.observe(update_r5, 'value')
def update_r6(*args):
    R6.write(R6_s.value)
R6_s.observe(update_r6, 'value')
def update_r7(*args):
    R7.write(R7_s.value)
R7_s.observe(update_r7, 'value')
def update_r8(*args):
    if (R8_s.value == 3):
        R8.write(4)
    else :R8.write(R8_s.value)
R8_s.observe(update_r8, 'value')
def update_textRegisters(*args):
    complete = R9_s.value
    if (len(complete) > 64):
        complete = complete[:(64-len(complete))]
    for x in range(0,64-len(complete)):
        complete = ' ' + complete
        
    text = 0
    for c in complete[:-60]:
        text = text << 8
        text += ord(c)
    R9.write(text)
    text = 0
    for c in complete[4:-56]:
        text = text << 8
        text += ord(c)
    R10.write(text)
    text = 0
    for c in complete[8:-52]:
        text = text << 8
        text += ord(c)
    R11.write(text)
    text = 0
    for c in complete[12:-48]:
        text = text << 8
        text += ord(c)
    R12.write(text)
    text = 0
    for c in complete[16:-44]:
        text = text << 8
        text += ord(c)
    R13.write(text)
    text = 0
    for c in complete[20:-40]:
        text = text << 8
        text += ord(c)
    R14.write(text)
    text = 0
    for c in complete[24:-36]:
        text = text << 8
        text += ord(c)
    R15.write(text)
    text = 0
    for c in complete[28:-32]:
        text = text << 8
        text += ord(c)
    R15.write(text)
    text = 0
    for c in complete[32:-28]:
        text = text << 8
        text += ord(c)
    R17.write(text)
    text = 0
    for c in complete[36:-24]:
        text = text << 8
        text += ord(c)
    R18.write(text)
    text = 0
    for c in complete[40:-20]:
        text = text << 8
        text += ord(c)
    R19.write(text)
    text = 0
    for c in complete[44:-16]:
        text = text << 8
        text += ord(c)
    R20.write(text)
    text = 0
    for c in complete[48:-12]:
        text = text << 8
        text += ord(c)
    R21.write(text)
    text = 0
    for c in complete[52:-8]:
        text = text << 8
        text += ord(c)
    R22.write(text)
    text = 0
    for c in complete[56:-4]:
        text = text << 8
        text += ord(c)
    R23.write(text)
    text = 0
    for c in complete[60:]:
        text = text << 8
        text += ord(c)
    R24.write(text)
R9_s.observe(update_textRegisters, 'value')

from IPython.display import clear_output
from ipywidgets import Button, HBox, VBox

words = ['HDMI Reset','Program']
items = [Button(description=w) for w in words]

def on_hdmi_clicked(b):
    hdmi_out.stop()
    hdmi_in.stop()
    hdmi_out.start()
    hdmi_in.start()
def on_program_clicked(b):
    Bitstream_Part("text_p.bit").download()
    olrd_str = "orld"
    lo_W_str = "lo W"
    hel_str = "Hel"
    olrd = 0
    for c in olrd_str:
        olrd = olrd << 8
        olrd += ord(c)
    lo_W = 0
    for c in lo_W_str:
        lo_W = lo_W << 8
        lo_W += ord(c)
    hel = 0
    for c in hel_str:
        hel = hel << 8
        hel += ord(c)
    R0.write(0)
    R1.write(150)
    R2.write(1150)
    R3.write(32)
    R4.write(0)
    R5.write(0)
    R6.write(0)
    R7.write(0)
    R8.write(1)
    R22.write(hel)
    R23.write(lo_W)
    R24.write(olrd)
    
items[0].on_click(on_hdmi_clicked)
items[1].on_click(on_program_clicked)

widgets.HBox([VBox([items[0], items[1]]),R0_s,R1_s, R2_s, R3_s, R4_s, R5_s, R6_s, R7_s, R8_s, R9_s])

5. User interface instructions

Buttons:
HDMI Reset - Resets the HDMI

Program - Programs and starts the text overlay

Sliders:
Y axis - Where the text appears vertically 

Left Limit - Where the text leaves the screen on the x axis  

Right Limit - Where the text enters the screen on the x axis

#Chars - The number of Charaters shown on the screen. The max it 64. If your text is shorter then this number, blank text will be added in font of the text. If your text is longer then this number the font of the text will be cut off.

Text Size - Size of text, This increases the font size by a factor of 2.

Red, Green, Blue - Font color

Speed -  The speed of the scrolling

Text box:
Text - The text to appear on the filter, max length of 64 characters.

(Note: to avoid any potential glitching, set the text size to 1 when changing the left and right limits or speed. If glitching does occur it will only happen during one iteration. If this is not the case and glitching continues, hit the program button again.)

5. Clean up

When you are done playing with filter, run the following code to stop the video stream


In [5]:
hdmi_out.stop()
hdmi_in.stop()
del hdmi_out
del hdmi_in

In [ ]: