#StackBounty: #python #pygame Exception has occurred: error mpg123_seek: Invalid RVA mode. (code 12)

Bounty: 50

I am recording audio using sounddevice and I want to play it through a virtual audio cable through pygame, I keep receiving this error Exception has occurred: error mpg123_seek: Invalid RVA mode. (code 12)

My code is below:

import sounddevice as sd
from scipy.io.wavfile import write
import random
import pygame
import time

pygame.init()
pygame.mixer.init(devicename='CABLE Input (VB-Audio Virtual Cable)')

fs = 44100  # Sample rate
seconds = 00.1  # Duration of recording


def main():
    for x in range(10000):
        number = random.randint(1,9999999)


        myrecording = sd.rec(int(seconds * fs), samplerate=fs, channels=2)
        sd.wait()  # Wait until recording is finished
        write(f'output/output{str(number)}.mp3', fs, myrecording)  # Save as WAV file `

        # PLAY MIC SOUND HERE
        pygame.mixer.music.load(f'output/output{str(number)}.mp3') #Load the mp3  
        pygame.mixer.music.play() #Play it
        time.sleep(00.1)

main()

Any help is appreciated.


Get this bounty!!!

#StackBounty: #ssh #pygame #framebuffer #computer-vision #xrdp Python pygame program won't run through SSH / Remote Desktop

Bounty: 50

I’ve been working on my own object recognition program based on the rpi-vision test program pitft_labeled_output.py (from this webpage). It’s basically a custom neural network model and a bit modified code for the new model to work. However, I’m having problems running my program through Remote Desktop. This is how I run my program (using venv from Graphic Labeling Demo):

pi@raspberrypi:~ $ sudo bash
root@raspberrypi:/home/pi# cd signcap && . ../rpi-vision/.venv/bin/activate
(.venv) root@raspberrypi:/home/pi/signcap# python3 src/dar_ts.py
pygame 1.9.6
Hello from the pygame community. https://www.pygame.org/contribute.html
No protocol specified
No protocol specified
No protocol specified
xcb_connection_has_error() returned true
No protocol specified
xcb_connection_has_error() returned true
INFO: Created TensorFlow Lite XNNPACK delegate for CPU.
No protocol specified
Unable to init server: Could not connect: Connection refused

(Mask:1359): Gtk-WARNING **: 20:00:31.012: cannot open display: :10.0

As you can see, I’m getting several "No protocol specified" errors and the display error. When I run echo $DISPLAY in a console when I’m connected through Remote Desktop, it prints :10.0.

When I run the pitft_labeled_output.py through Remote Desktop like:

sudo bash
root@raspberrypi:/home/pi# cd rpi-vision && . .venv/bin/activate
(.venv) root@raspberrypi:/home/pi/rpi-vision# python3 tests/pitft_labeled_output.py

The display is successfully opened and everything works as it should.

However, my program works fine locally or through VNC. When I’m connected through VNC and run echo $DISPLAY, I get :1.0.
What could be the issue that it doesn’t work through Remote Desktop, but pitft_labeled_output.py does?

Here is the code of my program so you can compare it with pitft_labeled_output.py from rpi-vision:

import time
import logging
import argparse
import pygame
import os
import sys
import numpy as np
import subprocess
import signal

# Environment variables for Braincraft HAT.
os.environ['SDL_FBDEV'] = "/dev/fb1"
os.environ['SDL_VIDEODRIVER'] = "fbcon"

def dont_quit(signal, frame):
   print('Caught signal: {}'.format(signal))
signal.signal(signal.SIGHUP, dont_quit)

from capture import PiCameraStream
from tsdar import TrafficSignDetectorAndRecognizer

# Initialize the logger.
logging.basicConfig()
logging.getLogger().setLevel(logging.INFO)

# Initialize the display.
pygame.init()
# Create a Surface object which is shown on the display.
# If size is set to (0,0), the created Surface will have the same size as the
# current screen resolution (240x240 for Braincraft HAT).
screen = pygame.display.set_mode((0,0), pygame.FULLSCREEN)
# Declare the capture manager for Pi Camera.
capture_manager = None

# Function for parsing program arguments.
def parse_args():
    parser = argparse.ArgumentParser()
    parser.add_argument('--rotation', type=int, choices=[0, 90, 180, 270],
                        dest='rotation', action='store', default=0,
                        help='Rotate everything on the display by this angle')
    args = parser.parse_args()
    return args

last_seen = []
already_seen = []

def main(args):
    global capture_manager, last_seen, already_seen

    # Initialize the capture manager to get stream from Pi Camera.
    if screen.get_width() == screen.get_height() or args.roation in (0, 180):
        capture_manager = PiCameraStream(resolution=(max(320, screen.get_width()), max(240, screen.get_height())), rotation=180, preview=False, format='rgb')
    else:
        capture_manager = PiCameraStream(resolution=(max(240, screen.get_height()), max(320, screen.get_width())), rotation=180, preview=False, format='rgb')

    # Initialize the buffer size to screen size.
    if args.rotation in (0, 180):
        buffer = pygame.Surface((screen.get_width(), screen.get_height()))
    else:
        buffer = pygame.Surface((screen.get_height(), screen.get_width()))

    # Hide the mouse from the screen.
    pygame.mouse.set_visible(False)
    # Initialize the screen to black.
    screen.fill((0,0,0))
    # Try to show the splash image on the screen (if the image exists), otherwise, leave screen black.
    try:
        splash = pygame.image.load(os.path.dirname(sys.argv[0])+'/bchatsplash.bmp')
        splash = pygame.transform.rotate(splash, args.rotation)
        screen.blit(splash, ((screen.get_width() / 2) - (splash.get_width() / 2),
                    (screen.get_height() / 2) - (splash.get_height() / 2)))
    except pygame.error:
        pass
    pygame.display.update()

    # Use the default font.
    smallfont = pygame.font.Font(None, 24)
    medfont = pygame.font.Font(None, 36)

    # Initialize the traffic sign detector and recognizer object with the path
    # to the TensorFlow Lite (tflite) neural network model.
    tsdar0 = TrafficSignDetectorAndRecognizer(os.path.dirname(sys.argv[0])+'/models/uw_tsdar_model_no_aug_w_opts.tflite')

    # Start getting capture from Pi Camera.
    capture_manager.start()

    while not capture_manager.stopped:
        # If the frame wasn't captured successfully, go to the next while iteration
        if capture_manager.frame is None:
            continue

        # Fill the buffer with black color
        buffer.fill((0,0,0))

        # Update the frame.
        rgb_frame = capture_manager.frame

        # Make predictions. If traffic signs were detected, a bounding rectangle
        # will be drawn around them.
        timestamp = time.monotonic()
        predictions, out_frame = tsdar0.predict(rgb_frame)
        delta = time.monotonic() - timestamp
        logging.info(predictions)
        logging.info("TFLite inference took %d ms, %0.1f FPS" % (delta * 1000, 1 / delta))

        # Make an image from a frame.
        previewframe = np.ascontiguousarray(out_frame)
        img = pygame.image.frombuffer(previewframe, capture_manager.camera.resolution, 'RGB')

        # Put the image into buffer.
        buffer.blit(img, (0, 0))

        # Add FPS and temperature on the top corner of the buffer.
        fpstext = "%0.1f FPS" % (1/delta,)
        fpstext_surface = smallfont.render(fpstext, True, (255, 0, 0))
        fpstext_position = (buffer.get_width()-10, 10) # Near the top right corner
        buffer.blit(fpstext_surface, fpstext_surface.get_rect(topright=fpstext_position))
        try:
            temp = int(open("/sys/class/thermal/thermal_zone0/temp").read()) / 1000
            temptext = "%dN{DEGREE SIGN}C" % temp
            temptext_surface = smallfont.render(temptext, True, (255, 0, 0))
            temptext_position = (buffer.get_width()-10, 30) # near the top right corner
            buffer.blit(temptext_surface, temptext_surface.get_rect(topright=temptext_position))
        except OSError:
            pass

        # Reset the detecttext vertical position.
        dtvp = 0

        # For each traffic sign that is recognized in the current frame (up to 3 signs),
        # its name will be printed on the screen and it will be announced if it already wasn't.
        for i in range(len(predictions)):
            p = predictions[i];
            name = tsdar0.CLASS_NAMES[p]
            print("Detected", name)

            last_seen.append(name)

            # Render sign name on the bottom of the buffer (if multiple signs detected,
            # current sign name is written above the previous sign name).           .
            detecttext = name
            detecttext_font = medfont
            detecttext_color = (255, 0, 0)
            detecttext_surface = detecttext_font.render(detecttext, True, detecttext_color)
            dtvp = buffer.get_height() - (i+1)*(detecttext_font.size(detecttext)[1]) - i*detecttext_font.size(detecttext)[1]//2
            detecttext_position = (buffer.get_width()//2, dtvp)
            buffer.blit(detecttext_surface, detecttext_surface.get_rect(center=detecttext_position))

            # Make an announcement for the traffic sign if it's new (not detected in previous consecutive frames).
            if detecttext not in already_seen:
                os.system('echo %s | festival --tts & ' % detecttext)

        # If new traffic signs were detected in the current frame, add them to already_seen list
        for ts in last_seen:
            if ts not in already_seen:
                already_seen.append(ts)

        # If the traffic sign disappeared from the frame (a car passed it), remove it from already_seen
        diff = list(set(already_seen)-set(last_seen))
        already_seen = [ts for ts in already_seen if ts not in diff]

        # Reset last_seen.
        last_seen = []

        # Show the buffer image on the screen.
        screen.blit(pygame.transform.rotate(buffer, args.rotation), (0,0))
        pygame.display.update()

# Run the program until it's interrupted by key press.
if __name__ == "__main__":
    args = parse_args()
    try:
        main(args)
    except KeyboardInterrupt:
        capture_manager.stop()

Edit:
To clarify a bit more, I first followed this tutorial to install my Braincraft HAT and then followed this one to try out the object recognition test example (pitft_labeled_output.py) from rpi-vision. Everything worked great through SSH. I saw logging info in the SSH console and the camera feed and recognized objects on the Braincraftt HAT display. Then I decided to try it out from Windows Remote Desktop (after installing xrdp on RPi) and it worked great. I saw logging info in terminal and camera feed on Braincraft display. But, when I wanted to run my program instead of pitft_labeled_output.py, I received the errors mentioned above. I even went further and replaced pitft_labeled_output.py code with my code(dar_ts.py) and ran my code as if I was running pitft_labeled_output.py (thought that there might be some dependencies inside rpi-vision folder), but it didn’t work, received the same error. What could be the issue with my code?

P.S. What also confused me further is that pitft_labeled_output.py has a typo in line 56 and runs fine anyway, but when I ran my code for the first time, it asked me to correct the error.
enter image description here


Get this bounty!!!

#StackBounty: #ssh #pygame #framebuffer #computer-vision #xrdp Python pygame program won't run through SSH / Remote Desktop

Bounty: 50

I’ve been working on my own object recognition program based on the rpi-vision test program pitft_labeled_output.py (from this webpage). It’s basically a custom neural network model and a bit modified code for the new model to work. However, I’m having problems running my program through Remote Desktop. This is how I run my program (using venv from Graphic Labeling Demo):

pi@raspberrypi:~ $ sudo bash
root@raspberrypi:/home/pi# cd signcap && . ../rpi-vision/.venv/bin/activate
(.venv) root@raspberrypi:/home/pi/signcap# python3 src/dar_ts.py
pygame 1.9.6
Hello from the pygame community. https://www.pygame.org/contribute.html
No protocol specified
No protocol specified
No protocol specified
xcb_connection_has_error() returned true
No protocol specified
xcb_connection_has_error() returned true
INFO: Created TensorFlow Lite XNNPACK delegate for CPU.
No protocol specified
Unable to init server: Could not connect: Connection refused

(Mask:1359): Gtk-WARNING **: 20:00:31.012: cannot open display: :10.0

As you can see, I’m getting several "No protocol specified" errors and the display error. When I run echo $DISPLAY in a console when I’m connected through Remote Desktop, it prints :10.0.

When I run the pitft_labeled_output.py through Remote Desktop like:

sudo bash
root@raspberrypi:/home/pi# cd rpi-vision && . .venv/bin/activate
(.venv) root@raspberrypi:/home/pi/rpi-vision# python3 tests/pitft_labeled_output.py

The display is successfully opened and everything works as it should.

However, my program works fine locally or through VNC. When I’m connected through VNC and run echo $DISPLAY, I get :1.0.
What could be the issue that it doesn’t work through Remote Desktop, but pitft_labeled_output.py does?

Here is the code of my program so you can compare it with pitft_labeled_output.py from rpi-vision:

import time
import logging
import argparse
import pygame
import os
import sys
import numpy as np
import subprocess
import signal

# Environment variables for Braincraft HAT.
os.environ['SDL_FBDEV'] = "/dev/fb1"
os.environ['SDL_VIDEODRIVER'] = "fbcon"

def dont_quit(signal, frame):
   print('Caught signal: {}'.format(signal))
signal.signal(signal.SIGHUP, dont_quit)

from capture import PiCameraStream
from tsdar import TrafficSignDetectorAndRecognizer

# Initialize the logger.
logging.basicConfig()
logging.getLogger().setLevel(logging.INFO)

# Initialize the display.
pygame.init()
# Create a Surface object which is shown on the display.
# If size is set to (0,0), the created Surface will have the same size as the
# current screen resolution (240x240 for Braincraft HAT).
screen = pygame.display.set_mode((0,0), pygame.FULLSCREEN)
# Declare the capture manager for Pi Camera.
capture_manager = None

# Function for parsing program arguments.
def parse_args():
    parser = argparse.ArgumentParser()
    parser.add_argument('--rotation', type=int, choices=[0, 90, 180, 270],
                        dest='rotation', action='store', default=0,
                        help='Rotate everything on the display by this angle')
    args = parser.parse_args()
    return args

last_seen = []
already_seen = []

def main(args):
    global capture_manager, last_seen, already_seen

    # Initialize the capture manager to get stream from Pi Camera.
    if screen.get_width() == screen.get_height() or args.roation in (0, 180):
        capture_manager = PiCameraStream(resolution=(max(320, screen.get_width()), max(240, screen.get_height())), rotation=180, preview=False, format='rgb')
    else:
        capture_manager = PiCameraStream(resolution=(max(240, screen.get_height()), max(320, screen.get_width())), rotation=180, preview=False, format='rgb')

    # Initialize the buffer size to screen size.
    if args.rotation in (0, 180):
        buffer = pygame.Surface((screen.get_width(), screen.get_height()))
    else:
        buffer = pygame.Surface((screen.get_height(), screen.get_width()))

    # Hide the mouse from the screen.
    pygame.mouse.set_visible(False)
    # Initialize the screen to black.
    screen.fill((0,0,0))
    # Try to show the splash image on the screen (if the image exists), otherwise, leave screen black.
    try:
        splash = pygame.image.load(os.path.dirname(sys.argv[0])+'/bchatsplash.bmp')
        splash = pygame.transform.rotate(splash, args.rotation)
        screen.blit(splash, ((screen.get_width() / 2) - (splash.get_width() / 2),
                    (screen.get_height() / 2) - (splash.get_height() / 2)))
    except pygame.error:
        pass
    pygame.display.update()

    # Use the default font.
    smallfont = pygame.font.Font(None, 24)
    medfont = pygame.font.Font(None, 36)

    # Initialize the traffic sign detector and recognizer object with the path
    # to the TensorFlow Lite (tflite) neural network model.
    tsdar0 = TrafficSignDetectorAndRecognizer(os.path.dirname(sys.argv[0])+'/models/uw_tsdar_model_no_aug_w_opts.tflite')

    # Start getting capture from Pi Camera.
    capture_manager.start()

    while not capture_manager.stopped:
        # If the frame wasn't captured successfully, go to the next while iteration
        if capture_manager.frame is None:
            continue

        # Fill the buffer with black color
        buffer.fill((0,0,0))

        # Update the frame.
        rgb_frame = capture_manager.frame

        # Make predictions. If traffic signs were detected, a bounding rectangle
        # will be drawn around them.
        timestamp = time.monotonic()
        predictions, out_frame = tsdar0.predict(rgb_frame)
        delta = time.monotonic() - timestamp
        logging.info(predictions)
        logging.info("TFLite inference took %d ms, %0.1f FPS" % (delta * 1000, 1 / delta))

        # Make an image from a frame.
        previewframe = np.ascontiguousarray(out_frame)
        img = pygame.image.frombuffer(previewframe, capture_manager.camera.resolution, 'RGB')

        # Put the image into buffer.
        buffer.blit(img, (0, 0))

        # Add FPS and temperature on the top corner of the buffer.
        fpstext = "%0.1f FPS" % (1/delta,)
        fpstext_surface = smallfont.render(fpstext, True, (255, 0, 0))
        fpstext_position = (buffer.get_width()-10, 10) # Near the top right corner
        buffer.blit(fpstext_surface, fpstext_surface.get_rect(topright=fpstext_position))
        try:
            temp = int(open("/sys/class/thermal/thermal_zone0/temp").read()) / 1000
            temptext = "%dN{DEGREE SIGN}C" % temp
            temptext_surface = smallfont.render(temptext, True, (255, 0, 0))
            temptext_position = (buffer.get_width()-10, 30) # near the top right corner
            buffer.blit(temptext_surface, temptext_surface.get_rect(topright=temptext_position))
        except OSError:
            pass

        # Reset the detecttext vertical position.
        dtvp = 0

        # For each traffic sign that is recognized in the current frame (up to 3 signs),
        # its name will be printed on the screen and it will be announced if it already wasn't.
        for i in range(len(predictions)):
            p = predictions[i];
            name = tsdar0.CLASS_NAMES[p]
            print("Detected", name)

            last_seen.append(name)

            # Render sign name on the bottom of the buffer (if multiple signs detected,
            # current sign name is written above the previous sign name).           .
            detecttext = name
            detecttext_font = medfont
            detecttext_color = (255, 0, 0)
            detecttext_surface = detecttext_font.render(detecttext, True, detecttext_color)
            dtvp = buffer.get_height() - (i+1)*(detecttext_font.size(detecttext)[1]) - i*detecttext_font.size(detecttext)[1]//2
            detecttext_position = (buffer.get_width()//2, dtvp)
            buffer.blit(detecttext_surface, detecttext_surface.get_rect(center=detecttext_position))

            # Make an announcement for the traffic sign if it's new (not detected in previous consecutive frames).
            if detecttext not in already_seen:
                os.system('echo %s | festival --tts & ' % detecttext)

        # If new traffic signs were detected in the current frame, add them to already_seen list
        for ts in last_seen:
            if ts not in already_seen:
                already_seen.append(ts)

        # If the traffic sign disappeared from the frame (a car passed it), remove it from already_seen
        diff = list(set(already_seen)-set(last_seen))
        already_seen = [ts for ts in already_seen if ts not in diff]

        # Reset last_seen.
        last_seen = []

        # Show the buffer image on the screen.
        screen.blit(pygame.transform.rotate(buffer, args.rotation), (0,0))
        pygame.display.update()

# Run the program until it's interrupted by key press.
if __name__ == "__main__":
    args = parse_args()
    try:
        main(args)
    except KeyboardInterrupt:
        capture_manager.stop()

Edit:
To clarify a bit more, I first followed this tutorial to install my Braincraft HAT and then followed this one to try out the object recognition test example (pitft_labeled_output.py) from rpi-vision. Everything worked great through SSH. I saw logging info in the SSH console and the camera feed and recognized objects on the Braincraftt HAT display. Then I decided to try it out from Windows Remote Desktop (after installing xrdp on RPi) and it worked great. I saw logging info in terminal and camera feed on Braincraft display. But, when I wanted to run my program instead of pitft_labeled_output.py, I received the errors mentioned above. I even went further and replaced pitft_labeled_output.py code with my code(dar_ts.py) and ran my code as if I was running pitft_labeled_output.py (thought that there might be some dependencies inside rpi-vision folder), but it didn’t work, received the same error. What could be the issue with my code?

P.S. What also confused me further is that pitft_labeled_output.py has a typo in line 56 and runs fine anyway, but when I ran my code for the first time, it asked me to correct the error.
enter image description here


Get this bounty!!!

#StackBounty: #ssh #pygame #framebuffer #computer-vision #xrdp Python pygame program won't run through SSH / Remote Desktop

Bounty: 50

I’ve been working on my own object recognition program based on the rpi-vision test program pitft_labeled_output.py (from this webpage). It’s basically a custom neural network model and a bit modified code for the new model to work. However, I’m having problems running my program through Remote Desktop. This is how I run my program (using venv from Graphic Labeling Demo):

pi@raspberrypi:~ $ sudo bash
root@raspberrypi:/home/pi# cd signcap && . ../rpi-vision/.venv/bin/activate
(.venv) root@raspberrypi:/home/pi/signcap# python3 src/dar_ts.py
pygame 1.9.6
Hello from the pygame community. https://www.pygame.org/contribute.html
No protocol specified
No protocol specified
No protocol specified
xcb_connection_has_error() returned true
No protocol specified
xcb_connection_has_error() returned true
INFO: Created TensorFlow Lite XNNPACK delegate for CPU.
No protocol specified
Unable to init server: Could not connect: Connection refused

(Mask:1359): Gtk-WARNING **: 20:00:31.012: cannot open display: :10.0

As you can see, I’m getting several "No protocol specified" errors and the display error. When I run echo $DISPLAY in a console when I’m connected through Remote Desktop, it prints :10.0.

When I run the pitft_labeled_output.py through Remote Desktop like:

sudo bash
root@raspberrypi:/home/pi# cd rpi-vision && . .venv/bin/activate
(.venv) root@raspberrypi:/home/pi/rpi-vision# python3 tests/pitft_labeled_output.py

The display is successfully opened and everything works as it should.

However, my program works fine locally or through VNC. When I’m connected through VNC and run echo $DISPLAY, I get :1.0.
What could be the issue that it doesn’t work through Remote Desktop, but pitft_labeled_output.py does?

Here is the code of my program so you can compare it with pitft_labeled_output.py from rpi-vision:

import time
import logging
import argparse
import pygame
import os
import sys
import numpy as np
import subprocess
import signal

# Environment variables for Braincraft HAT.
os.environ['SDL_FBDEV'] = "/dev/fb1"
os.environ['SDL_VIDEODRIVER'] = "fbcon"

def dont_quit(signal, frame):
   print('Caught signal: {}'.format(signal))
signal.signal(signal.SIGHUP, dont_quit)

from capture import PiCameraStream
from tsdar import TrafficSignDetectorAndRecognizer

# Initialize the logger.
logging.basicConfig()
logging.getLogger().setLevel(logging.INFO)

# Initialize the display.
pygame.init()
# Create a Surface object which is shown on the display.
# If size is set to (0,0), the created Surface will have the same size as the
# current screen resolution (240x240 for Braincraft HAT).
screen = pygame.display.set_mode((0,0), pygame.FULLSCREEN)
# Declare the capture manager for Pi Camera.
capture_manager = None

# Function for parsing program arguments.
def parse_args():
    parser = argparse.ArgumentParser()
    parser.add_argument('--rotation', type=int, choices=[0, 90, 180, 270],
                        dest='rotation', action='store', default=0,
                        help='Rotate everything on the display by this angle')
    args = parser.parse_args()
    return args

last_seen = []
already_seen = []

def main(args):
    global capture_manager, last_seen, already_seen

    # Initialize the capture manager to get stream from Pi Camera.
    if screen.get_width() == screen.get_height() or args.roation in (0, 180):
        capture_manager = PiCameraStream(resolution=(max(320, screen.get_width()), max(240, screen.get_height())), rotation=180, preview=False, format='rgb')
    else:
        capture_manager = PiCameraStream(resolution=(max(240, screen.get_height()), max(320, screen.get_width())), rotation=180, preview=False, format='rgb')

    # Initialize the buffer size to screen size.
    if args.rotation in (0, 180):
        buffer = pygame.Surface((screen.get_width(), screen.get_height()))
    else:
        buffer = pygame.Surface((screen.get_height(), screen.get_width()))

    # Hide the mouse from the screen.
    pygame.mouse.set_visible(False)
    # Initialize the screen to black.
    screen.fill((0,0,0))
    # Try to show the splash image on the screen (if the image exists), otherwise, leave screen black.
    try:
        splash = pygame.image.load(os.path.dirname(sys.argv[0])+'/bchatsplash.bmp')
        splash = pygame.transform.rotate(splash, args.rotation)
        screen.blit(splash, ((screen.get_width() / 2) - (splash.get_width() / 2),
                    (screen.get_height() / 2) - (splash.get_height() / 2)))
    except pygame.error:
        pass
    pygame.display.update()

    # Use the default font.
    smallfont = pygame.font.Font(None, 24)
    medfont = pygame.font.Font(None, 36)

    # Initialize the traffic sign detector and recognizer object with the path
    # to the TensorFlow Lite (tflite) neural network model.
    tsdar0 = TrafficSignDetectorAndRecognizer(os.path.dirname(sys.argv[0])+'/models/uw_tsdar_model_no_aug_w_opts.tflite')

    # Start getting capture from Pi Camera.
    capture_manager.start()

    while not capture_manager.stopped:
        # If the frame wasn't captured successfully, go to the next while iteration
        if capture_manager.frame is None:
            continue

        # Fill the buffer with black color
        buffer.fill((0,0,0))

        # Update the frame.
        rgb_frame = capture_manager.frame

        # Make predictions. If traffic signs were detected, a bounding rectangle
        # will be drawn around them.
        timestamp = time.monotonic()
        predictions, out_frame = tsdar0.predict(rgb_frame)
        delta = time.monotonic() - timestamp
        logging.info(predictions)
        logging.info("TFLite inference took %d ms, %0.1f FPS" % (delta * 1000, 1 / delta))

        # Make an image from a frame.
        previewframe = np.ascontiguousarray(out_frame)
        img = pygame.image.frombuffer(previewframe, capture_manager.camera.resolution, 'RGB')

        # Put the image into buffer.
        buffer.blit(img, (0, 0))

        # Add FPS and temperature on the top corner of the buffer.
        fpstext = "%0.1f FPS" % (1/delta,)
        fpstext_surface = smallfont.render(fpstext, True, (255, 0, 0))
        fpstext_position = (buffer.get_width()-10, 10) # Near the top right corner
        buffer.blit(fpstext_surface, fpstext_surface.get_rect(topright=fpstext_position))
        try:
            temp = int(open("/sys/class/thermal/thermal_zone0/temp").read()) / 1000
            temptext = "%dN{DEGREE SIGN}C" % temp
            temptext_surface = smallfont.render(temptext, True, (255, 0, 0))
            temptext_position = (buffer.get_width()-10, 30) # near the top right corner
            buffer.blit(temptext_surface, temptext_surface.get_rect(topright=temptext_position))
        except OSError:
            pass

        # Reset the detecttext vertical position.
        dtvp = 0

        # For each traffic sign that is recognized in the current frame (up to 3 signs),
        # its name will be printed on the screen and it will be announced if it already wasn't.
        for i in range(len(predictions)):
            p = predictions[i];
            name = tsdar0.CLASS_NAMES[p]
            print("Detected", name)

            last_seen.append(name)

            # Render sign name on the bottom of the buffer (if multiple signs detected,
            # current sign name is written above the previous sign name).           .
            detecttext = name
            detecttext_font = medfont
            detecttext_color = (255, 0, 0)
            detecttext_surface = detecttext_font.render(detecttext, True, detecttext_color)
            dtvp = buffer.get_height() - (i+1)*(detecttext_font.size(detecttext)[1]) - i*detecttext_font.size(detecttext)[1]//2
            detecttext_position = (buffer.get_width()//2, dtvp)
            buffer.blit(detecttext_surface, detecttext_surface.get_rect(center=detecttext_position))

            # Make an announcement for the traffic sign if it's new (not detected in previous consecutive frames).
            if detecttext not in already_seen:
                os.system('echo %s | festival --tts & ' % detecttext)

        # If new traffic signs were detected in the current frame, add them to already_seen list
        for ts in last_seen:
            if ts not in already_seen:
                already_seen.append(ts)

        # If the traffic sign disappeared from the frame (a car passed it), remove it from already_seen
        diff = list(set(already_seen)-set(last_seen))
        already_seen = [ts for ts in already_seen if ts not in diff]

        # Reset last_seen.
        last_seen = []

        # Show the buffer image on the screen.
        screen.blit(pygame.transform.rotate(buffer, args.rotation), (0,0))
        pygame.display.update()

# Run the program until it's interrupted by key press.
if __name__ == "__main__":
    args = parse_args()
    try:
        main(args)
    except KeyboardInterrupt:
        capture_manager.stop()

Edit:
To clarify a bit more, I first followed this tutorial to install my Braincraft HAT and then followed this one to try out the object recognition test example (pitft_labeled_output.py) from rpi-vision. Everything worked great through SSH. I saw logging info in the SSH console and the camera feed and recognized objects on the Braincraftt HAT display. Then I decided to try it out from Windows Remote Desktop (after installing xrdp on RPi) and it worked great. I saw logging info in terminal and camera feed on Braincraft display. But, when I wanted to run my program instead of pitft_labeled_output.py, I received the errors mentioned above. I even went further and replaced pitft_labeled_output.py code with my code(dar_ts.py) and ran my code as if I was running pitft_labeled_output.py (thought that there might be some dependencies inside rpi-vision folder), but it didn’t work, received the same error. What could be the issue with my code?

P.S. What also confused me further is that pitft_labeled_output.py has a typo in line 56 and runs fine anyway, but when I ran my code for the first time, it asked me to correct the error.
enter image description here


Get this bounty!!!

#StackBounty: #ssh #pygame #framebuffer #computer-vision #xrdp Python pygame program won't run through SSH / Remote Desktop

Bounty: 50

I’ve been working on my own object recognition program based on the rpi-vision test program pitft_labeled_output.py (from this webpage). It’s basically a custom neural network model and a bit modified code for the new model to work. However, I’m having problems running my program through Remote Desktop. This is how I run my program (using venv from Graphic Labeling Demo):

pi@raspberrypi:~ $ sudo bash
root@raspberrypi:/home/pi# cd signcap && . ../rpi-vision/.venv/bin/activate
(.venv) root@raspberrypi:/home/pi/signcap# python3 src/dar_ts.py
pygame 1.9.6
Hello from the pygame community. https://www.pygame.org/contribute.html
No protocol specified
No protocol specified
No protocol specified
xcb_connection_has_error() returned true
No protocol specified
xcb_connection_has_error() returned true
INFO: Created TensorFlow Lite XNNPACK delegate for CPU.
No protocol specified
Unable to init server: Could not connect: Connection refused

(Mask:1359): Gtk-WARNING **: 20:00:31.012: cannot open display: :10.0

As you can see, I’m getting several "No protocol specified" errors and the display error. When I run echo $DISPLAY in a console when I’m connected through Remote Desktop, it prints :10.0.

When I run the pitft_labeled_output.py through Remote Desktop like:

sudo bash
root@raspberrypi:/home/pi# cd rpi-vision && . .venv/bin/activate
(.venv) root@raspberrypi:/home/pi/rpi-vision# python3 tests/pitft_labeled_output.py

The display is successfully opened and everything works as it should.

However, my program works fine locally or through VNC. When I’m connected through VNC and run echo $DISPLAY, I get :1.0.
What could be the issue that it doesn’t work through Remote Desktop, but pitft_labeled_output.py does?

Here is the code of my program so you can compare it with pitft_labeled_output.py from rpi-vision:

import time
import logging
import argparse
import pygame
import os
import sys
import numpy as np
import subprocess
import signal

# Environment variables for Braincraft HAT.
os.environ['SDL_FBDEV'] = "/dev/fb1"
os.environ['SDL_VIDEODRIVER'] = "fbcon"

def dont_quit(signal, frame):
   print('Caught signal: {}'.format(signal))
signal.signal(signal.SIGHUP, dont_quit)

from capture import PiCameraStream
from tsdar import TrafficSignDetectorAndRecognizer

# Initialize the logger.
logging.basicConfig()
logging.getLogger().setLevel(logging.INFO)

# Initialize the display.
pygame.init()
# Create a Surface object which is shown on the display.
# If size is set to (0,0), the created Surface will have the same size as the
# current screen resolution (240x240 for Braincraft HAT).
screen = pygame.display.set_mode((0,0), pygame.FULLSCREEN)
# Declare the capture manager for Pi Camera.
capture_manager = None

# Function for parsing program arguments.
def parse_args():
    parser = argparse.ArgumentParser()
    parser.add_argument('--rotation', type=int, choices=[0, 90, 180, 270],
                        dest='rotation', action='store', default=0,
                        help='Rotate everything on the display by this angle')
    args = parser.parse_args()
    return args

last_seen = []
already_seen = []

def main(args):
    global capture_manager, last_seen, already_seen

    # Initialize the capture manager to get stream from Pi Camera.
    if screen.get_width() == screen.get_height() or args.roation in (0, 180):
        capture_manager = PiCameraStream(resolution=(max(320, screen.get_width()), max(240, screen.get_height())), rotation=180, preview=False, format='rgb')
    else:
        capture_manager = PiCameraStream(resolution=(max(240, screen.get_height()), max(320, screen.get_width())), rotation=180, preview=False, format='rgb')

    # Initialize the buffer size to screen size.
    if args.rotation in (0, 180):
        buffer = pygame.Surface((screen.get_width(), screen.get_height()))
    else:
        buffer = pygame.Surface((screen.get_height(), screen.get_width()))

    # Hide the mouse from the screen.
    pygame.mouse.set_visible(False)
    # Initialize the screen to black.
    screen.fill((0,0,0))
    # Try to show the splash image on the screen (if the image exists), otherwise, leave screen black.
    try:
        splash = pygame.image.load(os.path.dirname(sys.argv[0])+'/bchatsplash.bmp')
        splash = pygame.transform.rotate(splash, args.rotation)
        screen.blit(splash, ((screen.get_width() / 2) - (splash.get_width() / 2),
                    (screen.get_height() / 2) - (splash.get_height() / 2)))
    except pygame.error:
        pass
    pygame.display.update()

    # Use the default font.
    smallfont = pygame.font.Font(None, 24)
    medfont = pygame.font.Font(None, 36)

    # Initialize the traffic sign detector and recognizer object with the path
    # to the TensorFlow Lite (tflite) neural network model.
    tsdar0 = TrafficSignDetectorAndRecognizer(os.path.dirname(sys.argv[0])+'/models/uw_tsdar_model_no_aug_w_opts.tflite')

    # Start getting capture from Pi Camera.
    capture_manager.start()

    while not capture_manager.stopped:
        # If the frame wasn't captured successfully, go to the next while iteration
        if capture_manager.frame is None:
            continue

        # Fill the buffer with black color
        buffer.fill((0,0,0))

        # Update the frame.
        rgb_frame = capture_manager.frame

        # Make predictions. If traffic signs were detected, a bounding rectangle
        # will be drawn around them.
        timestamp = time.monotonic()
        predictions, out_frame = tsdar0.predict(rgb_frame)
        delta = time.monotonic() - timestamp
        logging.info(predictions)
        logging.info("TFLite inference took %d ms, %0.1f FPS" % (delta * 1000, 1 / delta))

        # Make an image from a frame.
        previewframe = np.ascontiguousarray(out_frame)
        img = pygame.image.frombuffer(previewframe, capture_manager.camera.resolution, 'RGB')

        # Put the image into buffer.
        buffer.blit(img, (0, 0))

        # Add FPS and temperature on the top corner of the buffer.
        fpstext = "%0.1f FPS" % (1/delta,)
        fpstext_surface = smallfont.render(fpstext, True, (255, 0, 0))
        fpstext_position = (buffer.get_width()-10, 10) # Near the top right corner
        buffer.blit(fpstext_surface, fpstext_surface.get_rect(topright=fpstext_position))
        try:
            temp = int(open("/sys/class/thermal/thermal_zone0/temp").read()) / 1000
            temptext = "%dN{DEGREE SIGN}C" % temp
            temptext_surface = smallfont.render(temptext, True, (255, 0, 0))
            temptext_position = (buffer.get_width()-10, 30) # near the top right corner
            buffer.blit(temptext_surface, temptext_surface.get_rect(topright=temptext_position))
        except OSError:
            pass

        # Reset the detecttext vertical position.
        dtvp = 0

        # For each traffic sign that is recognized in the current frame (up to 3 signs),
        # its name will be printed on the screen and it will be announced if it already wasn't.
        for i in range(len(predictions)):
            p = predictions[i];
            name = tsdar0.CLASS_NAMES[p]
            print("Detected", name)

            last_seen.append(name)

            # Render sign name on the bottom of the buffer (if multiple signs detected,
            # current sign name is written above the previous sign name).           .
            detecttext = name
            detecttext_font = medfont
            detecttext_color = (255, 0, 0)
            detecttext_surface = detecttext_font.render(detecttext, True, detecttext_color)
            dtvp = buffer.get_height() - (i+1)*(detecttext_font.size(detecttext)[1]) - i*detecttext_font.size(detecttext)[1]//2
            detecttext_position = (buffer.get_width()//2, dtvp)
            buffer.blit(detecttext_surface, detecttext_surface.get_rect(center=detecttext_position))

            # Make an announcement for the traffic sign if it's new (not detected in previous consecutive frames).
            if detecttext not in already_seen:
                os.system('echo %s | festival --tts & ' % detecttext)

        # If new traffic signs were detected in the current frame, add them to already_seen list
        for ts in last_seen:
            if ts not in already_seen:
                already_seen.append(ts)

        # If the traffic sign disappeared from the frame (a car passed it), remove it from already_seen
        diff = list(set(already_seen)-set(last_seen))
        already_seen = [ts for ts in already_seen if ts not in diff]

        # Reset last_seen.
        last_seen = []

        # Show the buffer image on the screen.
        screen.blit(pygame.transform.rotate(buffer, args.rotation), (0,0))
        pygame.display.update()

# Run the program until it's interrupted by key press.
if __name__ == "__main__":
    args = parse_args()
    try:
        main(args)
    except KeyboardInterrupt:
        capture_manager.stop()

Edit:
To clarify a bit more, I first followed this tutorial to install my Braincraft HAT and then followed this one to try out the object recognition test example (pitft_labeled_output.py) from rpi-vision. Everything worked great through SSH. I saw logging info in the SSH console and the camera feed and recognized objects on the Braincraftt HAT display. Then I decided to try it out from Windows Remote Desktop (after installing xrdp on RPi) and it worked great. I saw logging info in terminal and camera feed on Braincraft display. But, when I wanted to run my program instead of pitft_labeled_output.py, I received the errors mentioned above. I even went further and replaced pitft_labeled_output.py code with my code(dar_ts.py) and ran my code as if I was running pitft_labeled_output.py (thought that there might be some dependencies inside rpi-vision folder), but it didn’t work, received the same error. What could be the issue with my code?

P.S. What also confused me further is that pitft_labeled_output.py has a typo in line 56 and runs fine anyway, but when I ran my code for the first time, it asked me to correct the error.
enter image description here


Get this bounty!!!

#StackBounty: #ssh #pygame #framebuffer #computer-vision #xrdp Python pygame program won't run through SSH / Remote Desktop

Bounty: 50

I’ve been working on my own object recognition program based on the rpi-vision test program pitft_labeled_output.py (from this webpage). It’s basically a custom neural network model and a bit modified code for the new model to work. However, I’m having problems running my program through Remote Desktop. This is how I run my program (using venv from Graphic Labeling Demo):

pi@raspberrypi:~ $ sudo bash
root@raspberrypi:/home/pi# cd signcap && . ../rpi-vision/.venv/bin/activate
(.venv) root@raspberrypi:/home/pi/signcap# python3 src/dar_ts.py
pygame 1.9.6
Hello from the pygame community. https://www.pygame.org/contribute.html
No protocol specified
No protocol specified
No protocol specified
xcb_connection_has_error() returned true
No protocol specified
xcb_connection_has_error() returned true
INFO: Created TensorFlow Lite XNNPACK delegate for CPU.
No protocol specified
Unable to init server: Could not connect: Connection refused

(Mask:1359): Gtk-WARNING **: 20:00:31.012: cannot open display: :10.0

As you can see, I’m getting several "No protocol specified" errors and the display error. When I run echo $DISPLAY in a console when I’m connected through Remote Desktop, it prints :10.0.

When I run the pitft_labeled_output.py through Remote Desktop like:

sudo bash
root@raspberrypi:/home/pi# cd rpi-vision && . .venv/bin/activate
(.venv) root@raspberrypi:/home/pi/rpi-vision# python3 tests/pitft_labeled_output.py

The display is successfully opened and everything works as it should.

However, my program works fine locally or through VNC. When I’m connected through VNC and run echo $DISPLAY, I get :1.0.
What could be the issue that it doesn’t work through Remote Desktop, but pitft_labeled_output.py does?

Here is the code of my program so you can compare it with pitft_labeled_output.py from rpi-vision:

import time
import logging
import argparse
import pygame
import os
import sys
import numpy as np
import subprocess
import signal

# Environment variables for Braincraft HAT.
os.environ['SDL_FBDEV'] = "/dev/fb1"
os.environ['SDL_VIDEODRIVER'] = "fbcon"

def dont_quit(signal, frame):
   print('Caught signal: {}'.format(signal))
signal.signal(signal.SIGHUP, dont_quit)

from capture import PiCameraStream
from tsdar import TrafficSignDetectorAndRecognizer

# Initialize the logger.
logging.basicConfig()
logging.getLogger().setLevel(logging.INFO)

# Initialize the display.
pygame.init()
# Create a Surface object which is shown on the display.
# If size is set to (0,0), the created Surface will have the same size as the
# current screen resolution (240x240 for Braincraft HAT).
screen = pygame.display.set_mode((0,0), pygame.FULLSCREEN)
# Declare the capture manager for Pi Camera.
capture_manager = None

# Function for parsing program arguments.
def parse_args():
    parser = argparse.ArgumentParser()
    parser.add_argument('--rotation', type=int, choices=[0, 90, 180, 270],
                        dest='rotation', action='store', default=0,
                        help='Rotate everything on the display by this angle')
    args = parser.parse_args()
    return args

last_seen = []
already_seen = []

def main(args):
    global capture_manager, last_seen, already_seen

    # Initialize the capture manager to get stream from Pi Camera.
    if screen.get_width() == screen.get_height() or args.roation in (0, 180):
        capture_manager = PiCameraStream(resolution=(max(320, screen.get_width()), max(240, screen.get_height())), rotation=180, preview=False, format='rgb')
    else:
        capture_manager = PiCameraStream(resolution=(max(240, screen.get_height()), max(320, screen.get_width())), rotation=180, preview=False, format='rgb')

    # Initialize the buffer size to screen size.
    if args.rotation in (0, 180):
        buffer = pygame.Surface((screen.get_width(), screen.get_height()))
    else:
        buffer = pygame.Surface((screen.get_height(), screen.get_width()))

    # Hide the mouse from the screen.
    pygame.mouse.set_visible(False)
    # Initialize the screen to black.
    screen.fill((0,0,0))
    # Try to show the splash image on the screen (if the image exists), otherwise, leave screen black.
    try:
        splash = pygame.image.load(os.path.dirname(sys.argv[0])+'/bchatsplash.bmp')
        splash = pygame.transform.rotate(splash, args.rotation)
        screen.blit(splash, ((screen.get_width() / 2) - (splash.get_width() / 2),
                    (screen.get_height() / 2) - (splash.get_height() / 2)))
    except pygame.error:
        pass
    pygame.display.update()

    # Use the default font.
    smallfont = pygame.font.Font(None, 24)
    medfont = pygame.font.Font(None, 36)

    # Initialize the traffic sign detector and recognizer object with the path
    # to the TensorFlow Lite (tflite) neural network model.
    tsdar0 = TrafficSignDetectorAndRecognizer(os.path.dirname(sys.argv[0])+'/models/uw_tsdar_model_no_aug_w_opts.tflite')

    # Start getting capture from Pi Camera.
    capture_manager.start()

    while not capture_manager.stopped:
        # If the frame wasn't captured successfully, go to the next while iteration
        if capture_manager.frame is None:
            continue

        # Fill the buffer with black color
        buffer.fill((0,0,0))

        # Update the frame.
        rgb_frame = capture_manager.frame

        # Make predictions. If traffic signs were detected, a bounding rectangle
        # will be drawn around them.
        timestamp = time.monotonic()
        predictions, out_frame = tsdar0.predict(rgb_frame)
        delta = time.monotonic() - timestamp
        logging.info(predictions)
        logging.info("TFLite inference took %d ms, %0.1f FPS" % (delta * 1000, 1 / delta))

        # Make an image from a frame.
        previewframe = np.ascontiguousarray(out_frame)
        img = pygame.image.frombuffer(previewframe, capture_manager.camera.resolution, 'RGB')

        # Put the image into buffer.
        buffer.blit(img, (0, 0))

        # Add FPS and temperature on the top corner of the buffer.
        fpstext = "%0.1f FPS" % (1/delta,)
        fpstext_surface = smallfont.render(fpstext, True, (255, 0, 0))
        fpstext_position = (buffer.get_width()-10, 10) # Near the top right corner
        buffer.blit(fpstext_surface, fpstext_surface.get_rect(topright=fpstext_position))
        try:
            temp = int(open("/sys/class/thermal/thermal_zone0/temp").read()) / 1000
            temptext = "%dN{DEGREE SIGN}C" % temp
            temptext_surface = smallfont.render(temptext, True, (255, 0, 0))
            temptext_position = (buffer.get_width()-10, 30) # near the top right corner
            buffer.blit(temptext_surface, temptext_surface.get_rect(topright=temptext_position))
        except OSError:
            pass

        # Reset the detecttext vertical position.
        dtvp = 0

        # For each traffic sign that is recognized in the current frame (up to 3 signs),
        # its name will be printed on the screen and it will be announced if it already wasn't.
        for i in range(len(predictions)):
            p = predictions[i];
            name = tsdar0.CLASS_NAMES[p]
            print("Detected", name)

            last_seen.append(name)

            # Render sign name on the bottom of the buffer (if multiple signs detected,
            # current sign name is written above the previous sign name).           .
            detecttext = name
            detecttext_font = medfont
            detecttext_color = (255, 0, 0)
            detecttext_surface = detecttext_font.render(detecttext, True, detecttext_color)
            dtvp = buffer.get_height() - (i+1)*(detecttext_font.size(detecttext)[1]) - i*detecttext_font.size(detecttext)[1]//2
            detecttext_position = (buffer.get_width()//2, dtvp)
            buffer.blit(detecttext_surface, detecttext_surface.get_rect(center=detecttext_position))

            # Make an announcement for the traffic sign if it's new (not detected in previous consecutive frames).
            if detecttext not in already_seen:
                os.system('echo %s | festival --tts & ' % detecttext)

        # If new traffic signs were detected in the current frame, add them to already_seen list
        for ts in last_seen:
            if ts not in already_seen:
                already_seen.append(ts)

        # If the traffic sign disappeared from the frame (a car passed it), remove it from already_seen
        diff = list(set(already_seen)-set(last_seen))
        already_seen = [ts for ts in already_seen if ts not in diff]

        # Reset last_seen.
        last_seen = []

        # Show the buffer image on the screen.
        screen.blit(pygame.transform.rotate(buffer, args.rotation), (0,0))
        pygame.display.update()

# Run the program until it's interrupted by key press.
if __name__ == "__main__":
    args = parse_args()
    try:
        main(args)
    except KeyboardInterrupt:
        capture_manager.stop()

Edit:
To clarify a bit more, I first followed this tutorial to install my Braincraft HAT and then followed this one to try out the object recognition test example (pitft_labeled_output.py) from rpi-vision. Everything worked great through SSH. I saw logging info in the SSH console and the camera feed and recognized objects on the Braincraftt HAT display. Then I decided to try it out from Windows Remote Desktop (after installing xrdp on RPi) and it worked great. I saw logging info in terminal and camera feed on Braincraft display. But, when I wanted to run my program instead of pitft_labeled_output.py, I received the errors mentioned above. I even went further and replaced pitft_labeled_output.py code with my code(dar_ts.py) and ran my code as if I was running pitft_labeled_output.py (thought that there might be some dependencies inside rpi-vision folder), but it didn’t work, received the same error. What could be the issue with my code?

P.S. What also confused me further is that pitft_labeled_output.py has a typo in line 56 and runs fine anyway, but when I ran my code for the first time, it asked me to correct the error.
enter image description here


Get this bounty!!!

#StackBounty: #ssh #pygame #framebuffer #computer-vision #xrdp Python pygame program won't run through SSH / Remote Desktop

Bounty: 50

I’ve been working on my own object recognition program based on the rpi-vision test program pitft_labeled_output.py (from this webpage). It’s basically a custom neural network model and a bit modified code for the new model to work. However, I’m having problems running my program through Remote Desktop. This is how I run my program (using venv from Graphic Labeling Demo):

pi@raspberrypi:~ $ sudo bash
root@raspberrypi:/home/pi# cd signcap && . ../rpi-vision/.venv/bin/activate
(.venv) root@raspberrypi:/home/pi/signcap# python3 src/dar_ts.py
pygame 1.9.6
Hello from the pygame community. https://www.pygame.org/contribute.html
No protocol specified
No protocol specified
No protocol specified
xcb_connection_has_error() returned true
No protocol specified
xcb_connection_has_error() returned true
INFO: Created TensorFlow Lite XNNPACK delegate for CPU.
No protocol specified
Unable to init server: Could not connect: Connection refused

(Mask:1359): Gtk-WARNING **: 20:00:31.012: cannot open display: :10.0

As you can see, I’m getting several "No protocol specified" errors and the display error. When I run echo $DISPLAY in a console when I’m connected through Remote Desktop, it prints :10.0.

When I run the pitft_labeled_output.py through Remote Desktop like:

sudo bash
root@raspberrypi:/home/pi# cd rpi-vision && . .venv/bin/activate
(.venv) root@raspberrypi:/home/pi/rpi-vision# python3 tests/pitft_labeled_output.py

The display is successfully opened and everything works as it should.

However, my program works fine locally or through VNC. When I’m connected through VNC and run echo $DISPLAY, I get :1.0.
What could be the issue that it doesn’t work through Remote Desktop, but pitft_labeled_output.py does?

Here is the code of my program so you can compare it with pitft_labeled_output.py from rpi-vision:

import time
import logging
import argparse
import pygame
import os
import sys
import numpy as np
import subprocess
import signal

# Environment variables for Braincraft HAT.
os.environ['SDL_FBDEV'] = "/dev/fb1"
os.environ['SDL_VIDEODRIVER'] = "fbcon"

def dont_quit(signal, frame):
   print('Caught signal: {}'.format(signal))
signal.signal(signal.SIGHUP, dont_quit)

from capture import PiCameraStream
from tsdar import TrafficSignDetectorAndRecognizer

# Initialize the logger.
logging.basicConfig()
logging.getLogger().setLevel(logging.INFO)

# Initialize the display.
pygame.init()
# Create a Surface object which is shown on the display.
# If size is set to (0,0), the created Surface will have the same size as the
# current screen resolution (240x240 for Braincraft HAT).
screen = pygame.display.set_mode((0,0), pygame.FULLSCREEN)
# Declare the capture manager for Pi Camera.
capture_manager = None

# Function for parsing program arguments.
def parse_args():
    parser = argparse.ArgumentParser()
    parser.add_argument('--rotation', type=int, choices=[0, 90, 180, 270],
                        dest='rotation', action='store', default=0,
                        help='Rotate everything on the display by this angle')
    args = parser.parse_args()
    return args

last_seen = []
already_seen = []

def main(args):
    global capture_manager, last_seen, already_seen

    # Initialize the capture manager to get stream from Pi Camera.
    if screen.get_width() == screen.get_height() or args.roation in (0, 180):
        capture_manager = PiCameraStream(resolution=(max(320, screen.get_width()), max(240, screen.get_height())), rotation=180, preview=False, format='rgb')
    else:
        capture_manager = PiCameraStream(resolution=(max(240, screen.get_height()), max(320, screen.get_width())), rotation=180, preview=False, format='rgb')

    # Initialize the buffer size to screen size.
    if args.rotation in (0, 180):
        buffer = pygame.Surface((screen.get_width(), screen.get_height()))
    else:
        buffer = pygame.Surface((screen.get_height(), screen.get_width()))

    # Hide the mouse from the screen.
    pygame.mouse.set_visible(False)
    # Initialize the screen to black.
    screen.fill((0,0,0))
    # Try to show the splash image on the screen (if the image exists), otherwise, leave screen black.
    try:
        splash = pygame.image.load(os.path.dirname(sys.argv[0])+'/bchatsplash.bmp')
        splash = pygame.transform.rotate(splash, args.rotation)
        screen.blit(splash, ((screen.get_width() / 2) - (splash.get_width() / 2),
                    (screen.get_height() / 2) - (splash.get_height() / 2)))
    except pygame.error:
        pass
    pygame.display.update()

    # Use the default font.
    smallfont = pygame.font.Font(None, 24)
    medfont = pygame.font.Font(None, 36)

    # Initialize the traffic sign detector and recognizer object with the path
    # to the TensorFlow Lite (tflite) neural network model.
    tsdar0 = TrafficSignDetectorAndRecognizer(os.path.dirname(sys.argv[0])+'/models/uw_tsdar_model_no_aug_w_opts.tflite')

    # Start getting capture from Pi Camera.
    capture_manager.start()

    while not capture_manager.stopped:
        # If the frame wasn't captured successfully, go to the next while iteration
        if capture_manager.frame is None:
            continue

        # Fill the buffer with black color
        buffer.fill((0,0,0))

        # Update the frame.
        rgb_frame = capture_manager.frame

        # Make predictions. If traffic signs were detected, a bounding rectangle
        # will be drawn around them.
        timestamp = time.monotonic()
        predictions, out_frame = tsdar0.predict(rgb_frame)
        delta = time.monotonic() - timestamp
        logging.info(predictions)
        logging.info("TFLite inference took %d ms, %0.1f FPS" % (delta * 1000, 1 / delta))

        # Make an image from a frame.
        previewframe = np.ascontiguousarray(out_frame)
        img = pygame.image.frombuffer(previewframe, capture_manager.camera.resolution, 'RGB')

        # Put the image into buffer.
        buffer.blit(img, (0, 0))

        # Add FPS and temperature on the top corner of the buffer.
        fpstext = "%0.1f FPS" % (1/delta,)
        fpstext_surface = smallfont.render(fpstext, True, (255, 0, 0))
        fpstext_position = (buffer.get_width()-10, 10) # Near the top right corner
        buffer.blit(fpstext_surface, fpstext_surface.get_rect(topright=fpstext_position))
        try:
            temp = int(open("/sys/class/thermal/thermal_zone0/temp").read()) / 1000
            temptext = "%dN{DEGREE SIGN}C" % temp
            temptext_surface = smallfont.render(temptext, True, (255, 0, 0))
            temptext_position = (buffer.get_width()-10, 30) # near the top right corner
            buffer.blit(temptext_surface, temptext_surface.get_rect(topright=temptext_position))
        except OSError:
            pass

        # Reset the detecttext vertical position.
        dtvp = 0

        # For each traffic sign that is recognized in the current frame (up to 3 signs),
        # its name will be printed on the screen and it will be announced if it already wasn't.
        for i in range(len(predictions)):
            p = predictions[i];
            name = tsdar0.CLASS_NAMES[p]
            print("Detected", name)

            last_seen.append(name)

            # Render sign name on the bottom of the buffer (if multiple signs detected,
            # current sign name is written above the previous sign name).           .
            detecttext = name
            detecttext_font = medfont
            detecttext_color = (255, 0, 0)
            detecttext_surface = detecttext_font.render(detecttext, True, detecttext_color)
            dtvp = buffer.get_height() - (i+1)*(detecttext_font.size(detecttext)[1]) - i*detecttext_font.size(detecttext)[1]//2
            detecttext_position = (buffer.get_width()//2, dtvp)
            buffer.blit(detecttext_surface, detecttext_surface.get_rect(center=detecttext_position))

            # Make an announcement for the traffic sign if it's new (not detected in previous consecutive frames).
            if detecttext not in already_seen:
                os.system('echo %s | festival --tts & ' % detecttext)

        # If new traffic signs were detected in the current frame, add them to already_seen list
        for ts in last_seen:
            if ts not in already_seen:
                already_seen.append(ts)

        # If the traffic sign disappeared from the frame (a car passed it), remove it from already_seen
        diff = list(set(already_seen)-set(last_seen))
        already_seen = [ts for ts in already_seen if ts not in diff]

        # Reset last_seen.
        last_seen = []

        # Show the buffer image on the screen.
        screen.blit(pygame.transform.rotate(buffer, args.rotation), (0,0))
        pygame.display.update()

# Run the program until it's interrupted by key press.
if __name__ == "__main__":
    args = parse_args()
    try:
        main(args)
    except KeyboardInterrupt:
        capture_manager.stop()

Edit:
To clarify a bit more, I first followed this tutorial to install my Braincraft HAT and then followed this one to try out the object recognition test example (pitft_labeled_output.py) from rpi-vision. Everything worked great through SSH. I saw logging info in the SSH console and the camera feed and recognized objects on the Braincraftt HAT display. Then I decided to try it out from Windows Remote Desktop (after installing xrdp on RPi) and it worked great. I saw logging info in terminal and camera feed on Braincraft display. But, when I wanted to run my program instead of pitft_labeled_output.py, I received the errors mentioned above. I even went further and replaced pitft_labeled_output.py code with my code(dar_ts.py) and ran my code as if I was running pitft_labeled_output.py (thought that there might be some dependencies inside rpi-vision folder), but it didn’t work, received the same error. What could be the issue with my code?

P.S. What also confused me further is that pitft_labeled_output.py has a typo in line 56 and runs fine anyway, but when I ran my code for the first time, it asked me to correct the error.
enter image description here


Get this bounty!!!

#StackBounty: #ssh #pygame #framebuffer #computer-vision #xrdp Python pygame program won't run through SSH / Remote Desktop

Bounty: 50

I’ve been working on my own object recognition program based on the rpi-vision test program pitft_labeled_output.py (from this webpage). It’s basically a custom neural network model and a bit modified code for the new model to work. However, I’m having problems running my program through Remote Desktop. This is how I run my program (using venv from Graphic Labeling Demo):

pi@raspberrypi:~ $ sudo bash
root@raspberrypi:/home/pi# cd signcap && . ../rpi-vision/.venv/bin/activate
(.venv) root@raspberrypi:/home/pi/signcap# python3 src/dar_ts.py
pygame 1.9.6
Hello from the pygame community. https://www.pygame.org/contribute.html
No protocol specified
No protocol specified
No protocol specified
xcb_connection_has_error() returned true
No protocol specified
xcb_connection_has_error() returned true
INFO: Created TensorFlow Lite XNNPACK delegate for CPU.
No protocol specified
Unable to init server: Could not connect: Connection refused

(Mask:1359): Gtk-WARNING **: 20:00:31.012: cannot open display: :10.0

As you can see, I’m getting several "No protocol specified" errors and the display error. When I run echo $DISPLAY in a console when I’m connected through Remote Desktop, it prints :10.0.

When I run the pitft_labeled_output.py through Remote Desktop like:

sudo bash
root@raspberrypi:/home/pi# cd rpi-vision && . .venv/bin/activate
(.venv) root@raspberrypi:/home/pi/rpi-vision# python3 tests/pitft_labeled_output.py

The display is successfully opened and everything works as it should.

However, my program works fine locally or through VNC. When I’m connected through VNC and run echo $DISPLAY, I get :1.0.
What could be the issue that it doesn’t work through Remote Desktop, but pitft_labeled_output.py does?

Here is the code of my program so you can compare it with pitft_labeled_output.py from rpi-vision:

import time
import logging
import argparse
import pygame
import os
import sys
import numpy as np
import subprocess
import signal

# Environment variables for Braincraft HAT.
os.environ['SDL_FBDEV'] = "/dev/fb1"
os.environ['SDL_VIDEODRIVER'] = "fbcon"

def dont_quit(signal, frame):
   print('Caught signal: {}'.format(signal))
signal.signal(signal.SIGHUP, dont_quit)

from capture import PiCameraStream
from tsdar import TrafficSignDetectorAndRecognizer

# Initialize the logger.
logging.basicConfig()
logging.getLogger().setLevel(logging.INFO)

# Initialize the display.
pygame.init()
# Create a Surface object which is shown on the display.
# If size is set to (0,0), the created Surface will have the same size as the
# current screen resolution (240x240 for Braincraft HAT).
screen = pygame.display.set_mode((0,0), pygame.FULLSCREEN)
# Declare the capture manager for Pi Camera.
capture_manager = None

# Function for parsing program arguments.
def parse_args():
    parser = argparse.ArgumentParser()
    parser.add_argument('--rotation', type=int, choices=[0, 90, 180, 270],
                        dest='rotation', action='store', default=0,
                        help='Rotate everything on the display by this angle')
    args = parser.parse_args()
    return args

last_seen = []
already_seen = []

def main(args):
    global capture_manager, last_seen, already_seen

    # Initialize the capture manager to get stream from Pi Camera.
    if screen.get_width() == screen.get_height() or args.roation in (0, 180):
        capture_manager = PiCameraStream(resolution=(max(320, screen.get_width()), max(240, screen.get_height())), rotation=180, preview=False, format='rgb')
    else:
        capture_manager = PiCameraStream(resolution=(max(240, screen.get_height()), max(320, screen.get_width())), rotation=180, preview=False, format='rgb')

    # Initialize the buffer size to screen size.
    if args.rotation in (0, 180):
        buffer = pygame.Surface((screen.get_width(), screen.get_height()))
    else:
        buffer = pygame.Surface((screen.get_height(), screen.get_width()))

    # Hide the mouse from the screen.
    pygame.mouse.set_visible(False)
    # Initialize the screen to black.
    screen.fill((0,0,0))
    # Try to show the splash image on the screen (if the image exists), otherwise, leave screen black.
    try:
        splash = pygame.image.load(os.path.dirname(sys.argv[0])+'/bchatsplash.bmp')
        splash = pygame.transform.rotate(splash, args.rotation)
        screen.blit(splash, ((screen.get_width() / 2) - (splash.get_width() / 2),
                    (screen.get_height() / 2) - (splash.get_height() / 2)))
    except pygame.error:
        pass
    pygame.display.update()

    # Use the default font.
    smallfont = pygame.font.Font(None, 24)
    medfont = pygame.font.Font(None, 36)

    # Initialize the traffic sign detector and recognizer object with the path
    # to the TensorFlow Lite (tflite) neural network model.
    tsdar0 = TrafficSignDetectorAndRecognizer(os.path.dirname(sys.argv[0])+'/models/uw_tsdar_model_no_aug_w_opts.tflite')

    # Start getting capture from Pi Camera.
    capture_manager.start()

    while not capture_manager.stopped:
        # If the frame wasn't captured successfully, go to the next while iteration
        if capture_manager.frame is None:
            continue

        # Fill the buffer with black color
        buffer.fill((0,0,0))

        # Update the frame.
        rgb_frame = capture_manager.frame

        # Make predictions. If traffic signs were detected, a bounding rectangle
        # will be drawn around them.
        timestamp = time.monotonic()
        predictions, out_frame = tsdar0.predict(rgb_frame)
        delta = time.monotonic() - timestamp
        logging.info(predictions)
        logging.info("TFLite inference took %d ms, %0.1f FPS" % (delta * 1000, 1 / delta))

        # Make an image from a frame.
        previewframe = np.ascontiguousarray(out_frame)
        img = pygame.image.frombuffer(previewframe, capture_manager.camera.resolution, 'RGB')

        # Put the image into buffer.
        buffer.blit(img, (0, 0))

        # Add FPS and temperature on the top corner of the buffer.
        fpstext = "%0.1f FPS" % (1/delta,)
        fpstext_surface = smallfont.render(fpstext, True, (255, 0, 0))
        fpstext_position = (buffer.get_width()-10, 10) # Near the top right corner
        buffer.blit(fpstext_surface, fpstext_surface.get_rect(topright=fpstext_position))
        try:
            temp = int(open("/sys/class/thermal/thermal_zone0/temp").read()) / 1000
            temptext = "%dN{DEGREE SIGN}C" % temp
            temptext_surface = smallfont.render(temptext, True, (255, 0, 0))
            temptext_position = (buffer.get_width()-10, 30) # near the top right corner
            buffer.blit(temptext_surface, temptext_surface.get_rect(topright=temptext_position))
        except OSError:
            pass

        # Reset the detecttext vertical position.
        dtvp = 0

        # For each traffic sign that is recognized in the current frame (up to 3 signs),
        # its name will be printed on the screen and it will be announced if it already wasn't.
        for i in range(len(predictions)):
            p = predictions[i];
            name = tsdar0.CLASS_NAMES[p]
            print("Detected", name)

            last_seen.append(name)

            # Render sign name on the bottom of the buffer (if multiple signs detected,
            # current sign name is written above the previous sign name).           .
            detecttext = name
            detecttext_font = medfont
            detecttext_color = (255, 0, 0)
            detecttext_surface = detecttext_font.render(detecttext, True, detecttext_color)
            dtvp = buffer.get_height() - (i+1)*(detecttext_font.size(detecttext)[1]) - i*detecttext_font.size(detecttext)[1]//2
            detecttext_position = (buffer.get_width()//2, dtvp)
            buffer.blit(detecttext_surface, detecttext_surface.get_rect(center=detecttext_position))

            # Make an announcement for the traffic sign if it's new (not detected in previous consecutive frames).
            if detecttext not in already_seen:
                os.system('echo %s | festival --tts & ' % detecttext)

        # If new traffic signs were detected in the current frame, add them to already_seen list
        for ts in last_seen:
            if ts not in already_seen:
                already_seen.append(ts)

        # If the traffic sign disappeared from the frame (a car passed it), remove it from already_seen
        diff = list(set(already_seen)-set(last_seen))
        already_seen = [ts for ts in already_seen if ts not in diff]

        # Reset last_seen.
        last_seen = []

        # Show the buffer image on the screen.
        screen.blit(pygame.transform.rotate(buffer, args.rotation), (0,0))
        pygame.display.update()

# Run the program until it's interrupted by key press.
if __name__ == "__main__":
    args = parse_args()
    try:
        main(args)
    except KeyboardInterrupt:
        capture_manager.stop()

Edit:
To clarify a bit more, I first followed this tutorial to install my Braincraft HAT and then followed this one to try out the object recognition test example (pitft_labeled_output.py) from rpi-vision. Everything worked great through SSH. I saw logging info in the SSH console and the camera feed and recognized objects on the Braincraftt HAT display. Then I decided to try it out from Windows Remote Desktop (after installing xrdp on RPi) and it worked great. I saw logging info in terminal and camera feed on Braincraft display. But, when I wanted to run my program instead of pitft_labeled_output.py, I received the errors mentioned above. I even went further and replaced pitft_labeled_output.py code with my code(dar_ts.py) and ran my code as if I was running pitft_labeled_output.py (thought that there might be some dependencies inside rpi-vision folder), but it didn’t work, received the same error. What could be the issue with my code?

P.S. What also confused me further is that pitft_labeled_output.py has a typo in line 56 and runs fine anyway, but when I ran my code for the first time, it asked me to correct the error.
enter image description here


Get this bounty!!!

#StackBounty: #ssh #pygame #framebuffer #computer-vision #xrdp Python pygame program won't run through SSH / Remote Desktop

Bounty: 50

I’ve been working on my own object recognition program based on the rpi-vision test program pitft_labeled_output.py (from this webpage). It’s basically a custom neural network model and a bit modified code for the new model to work. However, I’m having problems running my program through Remote Desktop. This is how I run my program (using venv from Graphic Labeling Demo):

pi@raspberrypi:~ $ sudo bash
root@raspberrypi:/home/pi# cd signcap && . ../rpi-vision/.venv/bin/activate
(.venv) root@raspberrypi:/home/pi/signcap# python3 src/dar_ts.py
pygame 1.9.6
Hello from the pygame community. https://www.pygame.org/contribute.html
No protocol specified
No protocol specified
No protocol specified
xcb_connection_has_error() returned true
No protocol specified
xcb_connection_has_error() returned true
INFO: Created TensorFlow Lite XNNPACK delegate for CPU.
No protocol specified
Unable to init server: Could not connect: Connection refused

(Mask:1359): Gtk-WARNING **: 20:00:31.012: cannot open display: :10.0

As you can see, I’m getting several "No protocol specified" errors and the display error. When I run echo $DISPLAY in a console when I’m connected through Remote Desktop, it prints :10.0.

When I run the pitft_labeled_output.py through Remote Desktop like:

sudo bash
root@raspberrypi:/home/pi# cd rpi-vision && . .venv/bin/activate
(.venv) root@raspberrypi:/home/pi/rpi-vision# python3 tests/pitft_labeled_output.py

The display is successfully opened and everything works as it should.

However, my program works fine locally or through VNC. When I’m connected through VNC and run echo $DISPLAY, I get :1.0.
What could be the issue that it doesn’t work through Remote Desktop, but pitft_labeled_output.py does?

Here is the code of my program so you can compare it with pitft_labeled_output.py from rpi-vision:

import time
import logging
import argparse
import pygame
import os
import sys
import numpy as np
import subprocess
import signal

# Environment variables for Braincraft HAT.
os.environ['SDL_FBDEV'] = "/dev/fb1"
os.environ['SDL_VIDEODRIVER'] = "fbcon"

def dont_quit(signal, frame):
   print('Caught signal: {}'.format(signal))
signal.signal(signal.SIGHUP, dont_quit)

from capture import PiCameraStream
from tsdar import TrafficSignDetectorAndRecognizer

# Initialize the logger.
logging.basicConfig()
logging.getLogger().setLevel(logging.INFO)

# Initialize the display.
pygame.init()
# Create a Surface object which is shown on the display.
# If size is set to (0,0), the created Surface will have the same size as the
# current screen resolution (240x240 for Braincraft HAT).
screen = pygame.display.set_mode((0,0), pygame.FULLSCREEN)
# Declare the capture manager for Pi Camera.
capture_manager = None

# Function for parsing program arguments.
def parse_args():
    parser = argparse.ArgumentParser()
    parser.add_argument('--rotation', type=int, choices=[0, 90, 180, 270],
                        dest='rotation', action='store', default=0,
                        help='Rotate everything on the display by this angle')
    args = parser.parse_args()
    return args

last_seen = []
already_seen = []

def main(args):
    global capture_manager, last_seen, already_seen

    # Initialize the capture manager to get stream from Pi Camera.
    if screen.get_width() == screen.get_height() or args.roation in (0, 180):
        capture_manager = PiCameraStream(resolution=(max(320, screen.get_width()), max(240, screen.get_height())), rotation=180, preview=False, format='rgb')
    else:
        capture_manager = PiCameraStream(resolution=(max(240, screen.get_height()), max(320, screen.get_width())), rotation=180, preview=False, format='rgb')

    # Initialize the buffer size to screen size.
    if args.rotation in (0, 180):
        buffer = pygame.Surface((screen.get_width(), screen.get_height()))
    else:
        buffer = pygame.Surface((screen.get_height(), screen.get_width()))

    # Hide the mouse from the screen.
    pygame.mouse.set_visible(False)
    # Initialize the screen to black.
    screen.fill((0,0,0))
    # Try to show the splash image on the screen (if the image exists), otherwise, leave screen black.
    try:
        splash = pygame.image.load(os.path.dirname(sys.argv[0])+'/bchatsplash.bmp')
        splash = pygame.transform.rotate(splash, args.rotation)
        screen.blit(splash, ((screen.get_width() / 2) - (splash.get_width() / 2),
                    (screen.get_height() / 2) - (splash.get_height() / 2)))
    except pygame.error:
        pass
    pygame.display.update()

    # Use the default font.
    smallfont = pygame.font.Font(None, 24)
    medfont = pygame.font.Font(None, 36)

    # Initialize the traffic sign detector and recognizer object with the path
    # to the TensorFlow Lite (tflite) neural network model.
    tsdar0 = TrafficSignDetectorAndRecognizer(os.path.dirname(sys.argv[0])+'/models/uw_tsdar_model_no_aug_w_opts.tflite')

    # Start getting capture from Pi Camera.
    capture_manager.start()

    while not capture_manager.stopped:
        # If the frame wasn't captured successfully, go to the next while iteration
        if capture_manager.frame is None:
            continue

        # Fill the buffer with black color
        buffer.fill((0,0,0))

        # Update the frame.
        rgb_frame = capture_manager.frame

        # Make predictions. If traffic signs were detected, a bounding rectangle
        # will be drawn around them.
        timestamp = time.monotonic()
        predictions, out_frame = tsdar0.predict(rgb_frame)
        delta = time.monotonic() - timestamp
        logging.info(predictions)
        logging.info("TFLite inference took %d ms, %0.1f FPS" % (delta * 1000, 1 / delta))

        # Make an image from a frame.
        previewframe = np.ascontiguousarray(out_frame)
        img = pygame.image.frombuffer(previewframe, capture_manager.camera.resolution, 'RGB')

        # Put the image into buffer.
        buffer.blit(img, (0, 0))

        # Add FPS and temperature on the top corner of the buffer.
        fpstext = "%0.1f FPS" % (1/delta,)
        fpstext_surface = smallfont.render(fpstext, True, (255, 0, 0))
        fpstext_position = (buffer.get_width()-10, 10) # Near the top right corner
        buffer.blit(fpstext_surface, fpstext_surface.get_rect(topright=fpstext_position))
        try:
            temp = int(open("/sys/class/thermal/thermal_zone0/temp").read()) / 1000
            temptext = "%dN{DEGREE SIGN}C" % temp
            temptext_surface = smallfont.render(temptext, True, (255, 0, 0))
            temptext_position = (buffer.get_width()-10, 30) # near the top right corner
            buffer.blit(temptext_surface, temptext_surface.get_rect(topright=temptext_position))
        except OSError:
            pass

        # Reset the detecttext vertical position.
        dtvp = 0

        # For each traffic sign that is recognized in the current frame (up to 3 signs),
        # its name will be printed on the screen and it will be announced if it already wasn't.
        for i in range(len(predictions)):
            p = predictions[i];
            name = tsdar0.CLASS_NAMES[p]
            print("Detected", name)

            last_seen.append(name)

            # Render sign name on the bottom of the buffer (if multiple signs detected,
            # current sign name is written above the previous sign name).           .
            detecttext = name
            detecttext_font = medfont
            detecttext_color = (255, 0, 0)
            detecttext_surface = detecttext_font.render(detecttext, True, detecttext_color)
            dtvp = buffer.get_height() - (i+1)*(detecttext_font.size(detecttext)[1]) - i*detecttext_font.size(detecttext)[1]//2
            detecttext_position = (buffer.get_width()//2, dtvp)
            buffer.blit(detecttext_surface, detecttext_surface.get_rect(center=detecttext_position))

            # Make an announcement for the traffic sign if it's new (not detected in previous consecutive frames).
            if detecttext not in already_seen:
                os.system('echo %s | festival --tts & ' % detecttext)

        # If new traffic signs were detected in the current frame, add them to already_seen list
        for ts in last_seen:
            if ts not in already_seen:
                already_seen.append(ts)

        # If the traffic sign disappeared from the frame (a car passed it), remove it from already_seen
        diff = list(set(already_seen)-set(last_seen))
        already_seen = [ts for ts in already_seen if ts not in diff]

        # Reset last_seen.
        last_seen = []

        # Show the buffer image on the screen.
        screen.blit(pygame.transform.rotate(buffer, args.rotation), (0,0))
        pygame.display.update()

# Run the program until it's interrupted by key press.
if __name__ == "__main__":
    args = parse_args()
    try:
        main(args)
    except KeyboardInterrupt:
        capture_manager.stop()

Edit:
To clarify a bit more, I first followed this tutorial to install my Braincraft HAT and then followed this one to try out the object recognition test example (pitft_labeled_output.py) from rpi-vision. Everything worked great through SSH. I saw logging info in the SSH console and the camera feed and recognized objects on the Braincraftt HAT display. Then I decided to try it out from Windows Remote Desktop (after installing xrdp on RPi) and it worked great. I saw logging info in terminal and camera feed on Braincraft display. But, when I wanted to run my program instead of pitft_labeled_output.py, I received the errors mentioned above. I even went further and replaced pitft_labeled_output.py code with my code(dar_ts.py) and ran my code as if I was running pitft_labeled_output.py (thought that there might be some dependencies inside rpi-vision folder), but it didn’t work, received the same error. What could be the issue with my code?

P.S. What also confused me further is that pitft_labeled_output.py has a typo in line 56 and runs fine anyway, but when I ran my code for the first time, it asked me to correct the error.
enter image description here


Get this bounty!!!

#StackBounty: #ssh #pygame #framebuffer #computer-vision #xrdp Python pygame program won't run through SSH / Remote Desktop

Bounty: 50

I’ve been working on my own object recognition program based on the rpi-vision test program pitft_labeled_output.py (from this webpage). It’s basically a custom neural network model and a bit modified code for the new model to work. However, I’m having problems running my program through Remote Desktop. This is how I run my program (using venv from Graphic Labeling Demo):

pi@raspberrypi:~ $ sudo bash
root@raspberrypi:/home/pi# cd signcap && . ../rpi-vision/.venv/bin/activate
(.venv) root@raspberrypi:/home/pi/signcap# python3 src/dar_ts.py
pygame 1.9.6
Hello from the pygame community. https://www.pygame.org/contribute.html
No protocol specified
No protocol specified
No protocol specified
xcb_connection_has_error() returned true
No protocol specified
xcb_connection_has_error() returned true
INFO: Created TensorFlow Lite XNNPACK delegate for CPU.
No protocol specified
Unable to init server: Could not connect: Connection refused

(Mask:1359): Gtk-WARNING **: 20:00:31.012: cannot open display: :10.0

As you can see, I’m getting several "No protocol specified" errors and the display error. When I run echo $DISPLAY in a console when I’m connected through Remote Desktop, it prints :10.0.

When I run the pitft_labeled_output.py through Remote Desktop like:

sudo bash
root@raspberrypi:/home/pi# cd rpi-vision && . .venv/bin/activate
(.venv) root@raspberrypi:/home/pi/rpi-vision# python3 tests/pitft_labeled_output.py

The display is successfully opened and everything works as it should.

However, my program works fine locally or through VNC. When I’m connected through VNC and run echo $DISPLAY, I get :1.0.
What could be the issue that it doesn’t work through Remote Desktop, but pitft_labeled_output.py does?

Here is the code of my program so you can compare it with pitft_labeled_output.py from rpi-vision:

import time
import logging
import argparse
import pygame
import os
import sys
import numpy as np
import subprocess
import signal

# Environment variables for Braincraft HAT.
os.environ['SDL_FBDEV'] = "/dev/fb1"
os.environ['SDL_VIDEODRIVER'] = "fbcon"

def dont_quit(signal, frame):
   print('Caught signal: {}'.format(signal))
signal.signal(signal.SIGHUP, dont_quit)

from capture import PiCameraStream
from tsdar import TrafficSignDetectorAndRecognizer

# Initialize the logger.
logging.basicConfig()
logging.getLogger().setLevel(logging.INFO)

# Initialize the display.
pygame.init()
# Create a Surface object which is shown on the display.
# If size is set to (0,0), the created Surface will have the same size as the
# current screen resolution (240x240 for Braincraft HAT).
screen = pygame.display.set_mode((0,0), pygame.FULLSCREEN)
# Declare the capture manager for Pi Camera.
capture_manager = None

# Function for parsing program arguments.
def parse_args():
    parser = argparse.ArgumentParser()
    parser.add_argument('--rotation', type=int, choices=[0, 90, 180, 270],
                        dest='rotation', action='store', default=0,
                        help='Rotate everything on the display by this angle')
    args = parser.parse_args()
    return args

last_seen = []
already_seen = []

def main(args):
    global capture_manager, last_seen, already_seen

    # Initialize the capture manager to get stream from Pi Camera.
    if screen.get_width() == screen.get_height() or args.roation in (0, 180):
        capture_manager = PiCameraStream(resolution=(max(320, screen.get_width()), max(240, screen.get_height())), rotation=180, preview=False, format='rgb')
    else:
        capture_manager = PiCameraStream(resolution=(max(240, screen.get_height()), max(320, screen.get_width())), rotation=180, preview=False, format='rgb')

    # Initialize the buffer size to screen size.
    if args.rotation in (0, 180):
        buffer = pygame.Surface((screen.get_width(), screen.get_height()))
    else:
        buffer = pygame.Surface((screen.get_height(), screen.get_width()))

    # Hide the mouse from the screen.
    pygame.mouse.set_visible(False)
    # Initialize the screen to black.
    screen.fill((0,0,0))
    # Try to show the splash image on the screen (if the image exists), otherwise, leave screen black.
    try:
        splash = pygame.image.load(os.path.dirname(sys.argv[0])+'/bchatsplash.bmp')
        splash = pygame.transform.rotate(splash, args.rotation)
        screen.blit(splash, ((screen.get_width() / 2) - (splash.get_width() / 2),
                    (screen.get_height() / 2) - (splash.get_height() / 2)))
    except pygame.error:
        pass
    pygame.display.update()

    # Use the default font.
    smallfont = pygame.font.Font(None, 24)
    medfont = pygame.font.Font(None, 36)

    # Initialize the traffic sign detector and recognizer object with the path
    # to the TensorFlow Lite (tflite) neural network model.
    tsdar0 = TrafficSignDetectorAndRecognizer(os.path.dirname(sys.argv[0])+'/models/uw_tsdar_model_no_aug_w_opts.tflite')

    # Start getting capture from Pi Camera.
    capture_manager.start()

    while not capture_manager.stopped:
        # If the frame wasn't captured successfully, go to the next while iteration
        if capture_manager.frame is None:
            continue

        # Fill the buffer with black color
        buffer.fill((0,0,0))

        # Update the frame.
        rgb_frame = capture_manager.frame

        # Make predictions. If traffic signs were detected, a bounding rectangle
        # will be drawn around them.
        timestamp = time.monotonic()
        predictions, out_frame = tsdar0.predict(rgb_frame)
        delta = time.monotonic() - timestamp
        logging.info(predictions)
        logging.info("TFLite inference took %d ms, %0.1f FPS" % (delta * 1000, 1 / delta))

        # Make an image from a frame.
        previewframe = np.ascontiguousarray(out_frame)
        img = pygame.image.frombuffer(previewframe, capture_manager.camera.resolution, 'RGB')

        # Put the image into buffer.
        buffer.blit(img, (0, 0))

        # Add FPS and temperature on the top corner of the buffer.
        fpstext = "%0.1f FPS" % (1/delta,)
        fpstext_surface = smallfont.render(fpstext, True, (255, 0, 0))
        fpstext_position = (buffer.get_width()-10, 10) # Near the top right corner
        buffer.blit(fpstext_surface, fpstext_surface.get_rect(topright=fpstext_position))
        try:
            temp = int(open("/sys/class/thermal/thermal_zone0/temp").read()) / 1000
            temptext = "%dN{DEGREE SIGN}C" % temp
            temptext_surface = smallfont.render(temptext, True, (255, 0, 0))
            temptext_position = (buffer.get_width()-10, 30) # near the top right corner
            buffer.blit(temptext_surface, temptext_surface.get_rect(topright=temptext_position))
        except OSError:
            pass

        # Reset the detecttext vertical position.
        dtvp = 0

        # For each traffic sign that is recognized in the current frame (up to 3 signs),
        # its name will be printed on the screen and it will be announced if it already wasn't.
        for i in range(len(predictions)):
            p = predictions[i];
            name = tsdar0.CLASS_NAMES[p]
            print("Detected", name)

            last_seen.append(name)

            # Render sign name on the bottom of the buffer (if multiple signs detected,
            # current sign name is written above the previous sign name).           .
            detecttext = name
            detecttext_font = medfont
            detecttext_color = (255, 0, 0)
            detecttext_surface = detecttext_font.render(detecttext, True, detecttext_color)
            dtvp = buffer.get_height() - (i+1)*(detecttext_font.size(detecttext)[1]) - i*detecttext_font.size(detecttext)[1]//2
            detecttext_position = (buffer.get_width()//2, dtvp)
            buffer.blit(detecttext_surface, detecttext_surface.get_rect(center=detecttext_position))

            # Make an announcement for the traffic sign if it's new (not detected in previous consecutive frames).
            if detecttext not in already_seen:
                os.system('echo %s | festival --tts & ' % detecttext)

        # If new traffic signs were detected in the current frame, add them to already_seen list
        for ts in last_seen:
            if ts not in already_seen:
                already_seen.append(ts)

        # If the traffic sign disappeared from the frame (a car passed it), remove it from already_seen
        diff = list(set(already_seen)-set(last_seen))
        already_seen = [ts for ts in already_seen if ts not in diff]

        # Reset last_seen.
        last_seen = []

        # Show the buffer image on the screen.
        screen.blit(pygame.transform.rotate(buffer, args.rotation), (0,0))
        pygame.display.update()

# Run the program until it's interrupted by key press.
if __name__ == "__main__":
    args = parse_args()
    try:
        main(args)
    except KeyboardInterrupt:
        capture_manager.stop()

Edit:
To clarify a bit more, I first followed this tutorial to install my Braincraft HAT and then followed this one to try out the object recognition test example (pitft_labeled_output.py) from rpi-vision. Everything worked great through SSH. I saw logging info in the SSH console and the camera feed and recognized objects on the Braincraftt HAT display. Then I decided to try it out from Windows Remote Desktop (after installing xrdp on RPi) and it worked great. I saw logging info in terminal and camera feed on Braincraft display. But, when I wanted to run my program instead of pitft_labeled_output.py, I received the errors mentioned above. I even went further and replaced pitft_labeled_output.py code with my code(dar_ts.py) and ran my code as if I was running pitft_labeled_output.py (thought that there might be some dependencies inside rpi-vision folder), but it didn’t work, received the same error. What could be the issue with my code?

P.S. What also confused me further is that pitft_labeled_output.py has a typo in line 56 and runs fine anyway, but when I ran my code for the first time, it asked me to correct the error.
enter image description here


Get this bounty!!!