Search code examples
pythonraspberry-piautostart

Launch an OpenCV python script from Boot without desktop or ssh connection on Raspberry Pi


Recently, I have been writing a python script that detects objects using the COCO dataset with a pre-trained model. I have run this code successfully on the desktop interface of the Raspberry Pi using the "Mu Editor". My ambition is to be able to auto run this code at boot on the Raspberry Pi without the need of a monitor or SSH connection. I realize that my OpenCV program utilizes GUI elements and therefore makes it extremely difficult to simply power on the Raspberry Pi and auto run my code. However, I was curious whether there is any method that can provide this functionality.

Methods I have tried:

  1. /etc/rc.local - Pi booted up but did not run my code.
  2. sudo crontab -e - Same issue. I would get to the desktop and nothing would happen. I assume my code is simply bypassed by the Raspberry Pi for some reason.
  3. [Desktop Entry] - This method was the closest to solving my issue. However, the Raspberry Pi would boot to the desktop and autorun my code. If I disconnected the HDMI cable to the raspberry pi, my code would not run. The optimal result is for the raspberry pi to run the code at boot without having to open the desktop interface.

I have attached the code below:

import cv2
import pyttsx3
import time

cap = cv2.VideoCapture(0)
cap.set(3, 640)
cap.set(4, 480)
time.sleep(10)

classNames = []
classFile = '/home/pi/Desktop/Object Detection/coco.names'
with open(classFile,'rt') as f:
    classNames = [line.rstrip() for line in f]

configurationPath = '/home/pi/Desktop/Object Detection/ssd_mobilenet_v3_large_coco_2020_01_14.pbtxt'
weightsPath = '/home/pi/Desktop/Object Detection/frozen_inference_graph.pb'

net = cv2.dnn_DetectionModel(weightsPath, configurationPath)
net.setInputSize(320, 320)
net.setInputScale(1.0 / 127.5)
net.setInputMean((127.5, 127.5, 127.5))
net.setInputSwapRB(True)

engine = pyttsx3.init()
while True:
    success, img = cap.read()
    img = cv2.rotate(img, cv2.ROTATE_180)
    classIds, confs, bbox = net.detect(img, confThreshold=0.55, nmsThreshold=0.2)
    if len(classIds) == 0:
        engine.say("no objects detected")
        engine.runAndWait()
        continue
    if len(classIds) != 0:
        for classId, confidence, box in zip(classIds.flatten(), confs.flatten(), bbox):
            className = classNames[classId - 1]
            str1 = str(className)
            print(str1)
            engine.say(str1 + "detected")
            engine.runAndWait()
        continue
    cv2.imshow('Output', img)
    cv2.waitKey(1)

One note I forgot to mention: I tried running my code in the terminal rather than the Mu Editor and was successful.

I have written a previous question around a month ago and received great advice from this community! Please let me know if there is any way (software or hardware additions) to autostart this script at boot without the use of a monitor or SSH connection. I would appreciate any advice!


Solution

  • You could use systemd to create a service on your raspberry. This will run your script on background when your system boot.

    You will find a lot of tutorials on the internet on how to configure it (like this one).