【问题标题】:Raspberry Pi - Autostart OpenCv-Script - Error with cv::imshow()Raspberry Pi - 自动启动 OpenCv 脚本 - cv::imshow() 出错
【发布时间】:2017-11-21 11:16:11
【问题描述】:

简短说明:

我想在启动后通过 systemd 服务脚本自动启动可执行文件(opencv 二进制文件,通过 c++ 生成),但我没有成功。

我将错误范围缩小到代码语句“cv::imshow(....)”,它会打开一个窗口并显示一个图像。此时代码抛出错误:“QXcbConnection: Could not connect to display”

但是,如果我手动执行 sh 脚本或二进制文件,两者都可以正常工作。我在 stackoverflow 上搜索了最常见的错误,并尝试修复所有我能找到的错误。我很确定:

  1. 我的服务文件实际上是在启动时运行的(直到发生错误)
  2. 手动执行二进制文件可以正常工作
  3. 手动执行 .sh 脚本可以正常工作
  4. 我没有运行时链接错误(请参阅 .sh-script)

如果有任何帮助,我将不胜感激。请帮我修复错误,并请向我解释为什么会首先出现此错误。非常感谢:)

.

我的系统:

Machine: Raspberry Pi 3 Model B
Architecture: arm32 / ARMv7
OS: NOOBS

.

我在 /etc/systemd/system/ (test.service) 中的脚本:

[Unit]
Description=lalala

[Service]
Type=oneshot
ExecStart=/bin/bash "/home/pi/Desktop/test.sh" start
ExecStop=/bin/bash "/home/pi/Desktop/test.sh" stop
RemainAfterExit=yes

[Install]
WantedBy=multi-user.target

此外,我确实执行了以下命令:

sudo chmod u+rwx /etc/systemd/system/test.service

sudo systemctl enable test

如果我手动启动服务,它会运行与启动过程中自动启动时相同的错误输出:

sudo systemctl enable test

.

我的 shell 脚本(test.sh):

#!/bin/sh -e

exec 2> /tmp/test.sh.log       # send stderr to a log file
exec 1>&2                      # send stdout to the same log file
set -x                         # tell sh to display commands before execution


echo "in script"


start() 
{
    echo "in start"

    sleep 30

    LD_LIBRARY_PATH=/usr/local/OpenCV/lib:/usr/local/SFML/lib:/usr/local/curl/lib:$LD_LIBRARY_PATH
    export LD_LIBRARY_PATH

    /home/pi/Desktop/test/main -e &
}


# THE OTHER CASES, NOT PUT IN HERE (stop, status)


case "$1" in
    start)
        start
        ;;
    stop)
        stop
        ;;
    status)
        status 
        ;;
    restart)
        stop
        start
        ;;
    *)
        echo "Usage:  {start|stop|status|restart}"
        exit 1
        ;;
esac

exit 0

.

我的源代码的最小示例:(可执行文件)

#include <opencv2/opencv.hpp>
#include <opencv2/core.hpp>
#include <opencv2/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>

int main()
{
    cv::Mat frame;
    cv::namedWindow("result", cv::WINDOW_NORMAL);

    ## CRASH

    return 0;
}

.

附注:

我知道有一个类似的线程(Run OpenCV script on start with imshow)。但由于这个问题没有解决方案,而且我有更多的信息要分享,我认为启动一个新线程会更合适。

【问题讨论】:

  • Stack Overflow 是一个面向专业和狂热程序员的问答网站。您可能想查看raspberrypi.stackexchange.comserverfault.com
  • 我认为您可能会在@JamesBrown 提供的页面中获得更详细的答案或解决方法。但是,您可能会问自己的问题是,计算机将如何解释来自终端的 GUI 命令?可能可以将它传递给设置“显示器”或类似的东西,但它更多的是(pc / rasberry pi的)配置问题而不是编程问题。另外,一般来说,如果程序不时在后​​台运行,它不应该有一个 GUI,只是一个文件的日志。
  • 请在此处阅读我的 cmets...stackoverflow.com/q/47090354/2836621

标签: bash opencv raspberry-pi systemd autostart


【解决方案1】:

幸运的是,我解决了这个问题:

问题出在我的服务脚本的配置中。我确实知道我需要一个 DISPLAY 变量来定位 X 显示器的位置,但我不知道它也需要授权这一事实。这个帖子帮我弄清楚了:

https://unix.stackexchange.com/questions/85244/setting-display-in-systemd-service-file

简而言之:

将这些添加到 /etc/serviced/service 中的 test.service 行中:

Environment=XAUTHORITY=/home/pi/.Xauthority
Environment=DISPLAY=:0.0

【讨论】:

  • 不存在此文件:/etc/serviced/service
  • 如何在 linux mendel os 中执行此操作 .. 我找不到 .Xauthority ..:(
【解决方案2】:
[Unit]
Description=lalala

[Service]
Type=oneshot
ExecStart=/bin/bash "/home/pi/Desktop/test.sh" start
ExecStop=/bin/bash "/home/pi/Desktop/test.sh" stop
RemainAfterExit=yes
Environment=XAUTHORITY=/home/pi/.Xauthority
Environment=DISPLAY=:0.0

[Install]
WantedBy=multi-user.target

完整代码

【讨论】:

    猜你喜欢
    • 2015-08-11
    • 2015-05-26
    • 2014-11-07
    • 2019-09-20
    • 2022-11-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多