我正在Raspberry Pi 4上构建一个生产服务器。Web应用程序是用Django编写的。我使用uWSGI作为应用服务器,Nginx作为反向代理。我遵循了许多建议
Digital Ocean
.
其中一项任务是从连接到RPi的USB摄像头流式传输帧。我的灵感是
post
来自PyImageSearch,但我想在Django中完成。我的OpenCV版本是4.5.2。
-
负责打开相机的类如下:
class VideoCamera(object):
def __init__(self):
self.video = cv2.VideoCapture(0)
(self.grabbed, self.frame) = self.video.read()
if not self.grabbed:
print("Can't open camera")
threading.Thread(target=self.update, args=()).start()
def __del__(self):
self.video.release()
def get_frame(self):
image = self.frame
_, jpeg = cv2.imencode('.jpg', image)
return jpeg.tobytes()
def update(self):
while True:
(self.grabbed, self.frame) = self.video.read()
-
这段代码在我的笔记本电脑和RPi 4上都运行良好,但仅在Django的开发服务器上运行良好。在生产服务器(Nginx+uWSGI)上运行后,我收到以下消息
sudo systemctl status uwsgi
:
uwsgi.service - uWSGI Emperor service
Loaded: loaded (/etc/systemd/system/uwsgi.service; enabled; vendor preset: enabled)
Active: active (running) since Fri 2021-05-21 10:12:09 CEST; 58min ago
Process: 371 ExecStartPre=/bin/bash -c mkdir -p /run/uwsgi; chown pi:video /run/uwsgi (code=exited, status=0/SUCCESS)
Main PID: 428 (uwsgi)
Status: "The Emperor is governing 1 vassals"
Tasks: 13 (limit: 4915)
CGroup: /system.slice/uwsgi.service
ââ428 /home/pi/HomeGuard/my_env/bin/uwsgi
ââ502 /home/pi/HomeGuard/my_env/bin/uwsgi
ââ560 /home/pi/HomeGuard/my_env/bin/uwsgi
ââ561 /home/pi/HomeGuard/my_env/bin/uwsgi
ââ562 /home/pi/HomeGuard/my_env/bin/uwsgi
ââ563 /home/pi/HomeGuard/my_env/bin/uwsgi
ââ564 /home/pi/HomeGuard/my_env/bin/uwsgi
ââ565 /home/pi/HomeGuard/my_env/bin/uwsgi
ââ566 /home/pi/HomeGuard/my_env/bin/uwsgi
ââ567 /home/pi/HomeGuard/my_env/bin/uwsgi
ââ568 /home/pi/HomeGuard/my_env/bin/uwsgi
ââ569 /home/pi/HomeGuard/my_env/bin/uwsgi
May 21 11:07:07 raspberrypi uwsgi[428]: Can't open camera
May 21 11:07:07 raspberrypi uwsgi[428]: Traceback (most recent call last):
May 21 11:07:07 raspberrypi uwsgi[428]: File "/home/pi/HomeGuard/my_env/lib/python3.7/site-packages/django/utils/text.py", line 300, in compress_sequence
May 21 11:07:07 raspberrypi uwsgi[428]: for item in sequence:
May 21 11:07:07 raspberrypi uwsgi[428]: File "/home/pi/HomeGuard/vision/views.py", line 36, in gen
May 21 11:07:07 raspberrypi uwsgi[428]: frame = camera.get_frame()
May 21 11:07:07 raspberrypi uwsgi[428]: File "/home/pi/HomeGuard/vision/views.py", line 26, in get_frame
May 21 11:07:07 raspberrypi uwsgi[428]: _, jpeg = cv2.imencode('.jpg', image)
May 21 11:07:07 raspberrypi uwsgi[428]: cv2.error: OpenCV(4.5.2) /home/pi/opencv/modules/imgcodecs/src/loadsave.cpp:896: error: (-215:Assertion failed) !image.empty() in function 'imencode'
May 21 11:07:07 raspberrypi uwsgi[428]: [pid: 562|app: 0|req: 3/5] 192.168.178.43 () {42 vars in 761 bytes} [Fri May 21 09:07:05 2021] GET /vision/camera-usb-streaming/ => generated 10 bytes in 2034 msecs
-
相机无法开始工作,可能是由于某些权限问题。
要使用相机,给定的用户应该是“视频”组的一部分。
我将用户“pi”和“www数据”添加到“视频”组中。
-
我的uWSGI配置文件(homeguard.ini)如下:
[uwsgi]
project = homeguard
uid = pi
base = /home/pi/HomeGuard
chdir = %(base)
home = %(base)/my_env
virtualenv = %(home)
pythonpath = %(base)
env = DJANGO_SETTINGS_MODULE=homeguard.settings
module = %(project).wsgi:application
master = true
processes = 10
socket = /run/uwsgi/%(project).sock
chown-socket = %(uid):video
chmod-socket = 777
enable-threads = true
vacuum = true
我设置777只是为了检查它是否有问题,但它没有帮助,我稍后会更改它。
-
套接字权限:
ls -l /run/uwsgi/
srwxrwxrwx 1 pi video 0 May 21 10:12 homeguard.sock
-
我的Nginx配置如下:
server {
listen 80;
server_name raspberrypi.local;
location = /favicon.ico { access_log off; log_not_found off; }
charset utf-8;
client_max_body_size 75M;
location /media/ {
alias /home/pi/HomeGuard/media/;
}
location /static/ {
alias /home/pi/HomeGuard/static/;
}
location / {
uwsgi_pass unix:/run/uwsgi/homeguard.sock;
include uwsgi_params;
}
}
-
我的uwsgi.service文件如下:
[Unit]
Description=uWSGI Emperor service
[Service]
ExecStartPre=/bin/bash -c 'mkdir -p /run/uwsgi; chown pi:video /run/uwsgi'
ExecStart=/home/pi/HomeGuard/my_env/bin/uwsgi --emperor /etc/uwsgi/sites
Restart=always
KillSignal=SIGQUIT
Type=notify
NotifyAccess=all
[Install]
WantedBy=multi-user.target
-
跑步后
sudo journalctl -u uwsgi
命令,日志如下:
May 21 10:12:08 raspberrypi systemd[1]: Starting uWSGI Emperor service...
May 21 10:12:09 raspberrypi uwsgi[428]: *** Starting uWSGI 2.0.19.1 (32bit) on [Fri May 21 10:12:09 2021] ***
May 21 10:12:09 raspberrypi uwsgi[428]: compiled with version: 8.3.0 on 17 June 2020 09:19:11
May 21 10:12:09 raspberrypi uwsgi[428]: os: Linux-5.10.17-v7l+
May 21 10:12:09 raspberrypi uwsgi[428]: nodename: raspberrypi
May 21 10:12:09 raspberrypi uwsgi[428]: machine: armv7l
May 21 10:12:09 raspberrypi uwsgi[428]: clock source: unix
May 21 10:12:09 raspberrypi uwsgi[428]: pcre jit disabled
May 21 10:12:09 raspberrypi uwsgi[428]: detected number of CPU cores: 4
May 21 10:12:09 raspberrypi uwsgi[428]: current working directory: /
May 21 10:12:09 raspberrypi uwsgi[428]: detected binary path: /home/pi/HomeGuard/my_env/bin/uwsgi
May 21 10:12:09 raspberrypi uwsgi[428]: uWSGI running as root, you can use --uid/--gid/--chroot options
May 21 10:12:09 raspberrypi uwsgi[428]: *** WARNING: you are running uWSGI as root !!! (use the --uid flag) ***
May 21 10:12:09 raspberrypi uwsgi[428]: *** WARNING: you are running uWSGI without its master process manager ***
May 21 10:12:09 raspberrypi uwsgi[428]: your processes number limit is 60527
May 21 10:12:09 raspberrypi uwsgi[428]: your memory page size is 4096 bytes
May 21 10:12:09 raspberrypi uwsgi[428]: detected max file descriptor number: 1024
May 21 10:12:09 raspberrypi systemd[1]: Started uWSGI Emperor service.
May 21 10:12:09 raspberrypi uwsgi[428]: *** starting uWSGI Emperor ***
May 21 10:12:09 raspberrypi uwsgi[428]: *** has_emperor mode detected (fd: 7) ***
May 21 10:12:09 raspberrypi uwsgi[428]: [uWSGI] getting INI configuration from homeguard.ini
May 21 10:12:09 raspberrypi uwsgi[428]: *** Starting uWSGI 2.0.19.1 (32bit) on [Fri May 21 10:12:09 2021] ***
May 21 10:12:09 raspberrypi uwsgi[428]: compiled with version: 8.3.0 on 17 June 2020 09:19:11
May 21 10:12:09 raspberrypi uwsgi[428]: os: Linux-5.10.17-v7l+
May 21 10:12:09 raspberrypi uwsgi[428]: nodename: raspberrypi
May 21 10:12:09 raspberrypi uwsgi[428]: machine: armv7l
May 21 10:12:09 raspberrypi uwsgi[428]: clock source: unix
May 21 10:12:09 raspberrypi uwsgi[428]: pcre jit disabled
May 21 10:12:09 raspberrypi uwsgi[428]: detected number of CPU cores: 4
May 21 10:12:09 raspberrypi uwsgi[428]: current working directory: /etc/uwsgi/sites
May 21 10:12:09 raspberrypi uwsgi[428]: detected binary path: /home/pi/HomeGuard/my_env/bin/uwsgi
May 21 10:12:09 raspberrypi uwsgi[428]: chdir() to /home/pi/HomeGuard
May 21 10:12:09 raspberrypi uwsgi[428]: your processes number limit is 60527
May 21 10:12:09 raspberrypi uwsgi[428]: your memory page size is 4096 bytes
May 21 10:12:09 raspberrypi uwsgi[428]: detected max file descriptor number: 1024
May 21 10:12:09 raspberrypi uwsgi[428]: lock engine: pthread robust mutexes
May 21 10:12:09 raspberrypi uwsgi[428]: thunder lock: disabled (you can enable it with --thunder-lock)
May 21 10:12:09 raspberrypi uwsgi[428]: uwsgi socket 0 bound to UNIX address /run/uwsgi/homeguard.sock fd 3
May 21 10:12:09 raspberrypi uwsgi[428]: setuid() to 1000
May 21 10:12:09 raspberrypi uwsgi[428]: Python version: 3.7.3 (default, Jan 22 2021, 20:04:44) [GCC 8.3.0]
May 21 10:12:09 raspberrypi uwsgi[428]: PEP 405 virtualenv detected: /home/pi/HomeGuard/my_env
May 21 10:12:09 raspberrypi uwsgi[428]: Set PythonHome to /home/pi/HomeGuard/my_env
May 21 10:12:10 raspberrypi uwsgi[428]: Python main interpreter initialized at 0xcb8f20
May 21 10:12:10 raspberrypi uwsgi[428]: python threads support enabled
May 21 10:12:10 raspberrypi uwsgi[428]: your server socket listen backlog is limited to 100 connections
May 21 10:12:10 raspberrypi uwsgi[428]: your mercy for graceful operations on workers is 60 seconds
May 21 10:12:10 raspberrypi uwsgi[428]: mapped 708488 bytes (691 KB) for 10 cores
May 21 10:12:10 raspberrypi uwsgi[428]: *** Operational MODE: preforking ***
May 21 10:12:10 raspberrypi uwsgi[428]: added /home/pi/HomeGuard/ to pythonpath.
May 21 10:12:12 raspberrypi uwsgi[428]: WSGI app 0 (mountpoint='') ready in 2 seconds on interpreter 0xcb8f20 pid: 502 (default $
May 21 10:12:12 raspberrypi uwsgi[428]: *** uWSGI is running in multiple interpreter mode ***
May 21 10:12:12 raspberrypi uwsgi[428]: spawned uWSGI master process (pid: 502)
May 21 10:12:12 raspberrypi uwsgi[428]: Fri May 21 10:12:12 2021 - [emperor] vassal homeguard.ini has been spawned
May 21 10:12:12 raspberrypi uwsgi[428]: spawned uWSGI worker 1 (pid: 560, cores: 1)
May 21 10:12:12 raspberrypi uwsgi[428]: spawned uWSGI worker 2 (pid: 561, cores: 1)
May 21 10:12:12 raspberrypi uwsgi[428]: Fri May 21 10:12:12 2021 - [emperor] vassal homeguard.ini is ready to accept requests
May 21 10:12:12 raspberrypi uwsgi[428]: spawned uWSGI worker 3 (pid: 562, cores: 1)
May 21 10:12:12 raspberrypi uwsgi[428]: spawned uWSGI worker 4 (pid: 563, cores: 1)
May 21 10:12:12 raspberrypi uwsgi[428]: spawned uWSGI worker 5 (pid: 564, cores: 1)
May 21 10:12:12 raspberrypi uwsgi[428]: spawned uWSGI worker 6 (pid: 565, cores: 1)
May 21 10:12:12 raspberrypi uwsgi[428]: spawned uWSGI worker 7 (pid: 566, cores: 1)
May 21 10:12:12 raspberrypi uwsgi[428]: spawned uWSGI worker 8 (pid: 567, cores: 1)
May 21 10:12:12 raspberrypi uwsgi[428]: spawned uWSGI worker 9 (pid: 568, cores: 1)
May 21 10:12:12 raspberrypi uwsgi[428]: spawned uWSGI worker 10 (pid: 569, cores: 1)
May 21 10:19:30 raspberrypi uwsgi[428]: [pid: 567|app: 0|req: 1/1] 192.168.178.43 () {40 vars in 639 bytes} [Fri May 21 08:19:26$
May 21 10:19:30 raspberrypi uwsgi[428]: announcing my loyalty to the Emperor...
May 21 10:19:30 raspberrypi uwsgi[428]: Fri May 21 10:19:30 2021 - [emperor] vassal homeguard.ini is now loyal
May 21 10:56:45 raspberrypi uwsgi[428]: [pid: 567|app: 0|req: 2/2] 192.168.178.43 () {40 vars in 639 bytes} [Fri May 21 08:56:45$
May 21 11:05:42 raspberrypi uwsgi[428]: [pid: 562|app: 0|req: 1/3] 192.168.178.43 () {40 vars in 639 bytes} [Fri May 21 09:05:41$
May 21 11:05:42 raspberrypi uwsgi[428]: announcing my loyalty to the Emperor...
May 21 11:05:42 raspberrypi uwsgi[428]: Fri May 21 11:05:42 2021 - [emperor] vassal homeguard.ini is now loyal
May 21 11:07:04 raspberrypi uwsgi[428]: [pid: 562|app: 0|req: 2/4] 192.168.178.43 () {42 vars in 730 bytes} [Fri May 21 09:07:04$
May 21 11:07:05 raspberrypi uwsgi[428]: [ WARN:0] global /home/pi/opencv/modules/videoio/src/cap_v4l.cpp (890) open VIDEOIO(V4L2$
May 21 11:07:07 raspberrypi uwsgi[428]: Can't open camera
May 21 11:07:07 raspberrypi uwsgi[428]: Traceback (most recent call last):
May 21 11:07:07 raspberrypi uwsgi[428]: File "/home/pi/HomeGuard/my_env/lib/python3.7/site-packages/django/utils/text.py", lin$
May 21 11:07:07 raspberrypi uwsgi[428]: for item in sequence:
May 21 11:07:07 raspberrypi uwsgi[428]: File "/home/pi/HomeGuard/vision/views.py", line 36, in gen
May 21 11:07:07 raspberrypi uwsgi[428]: frame = camera.get_frame()
May 21 11:07:07 raspberrypi uwsgi[428]: File "/home/pi/HomeGuard/vision/views.py", line 26, in get_frame
May 21 11:07:07 raspberrypi uwsgi[428]: _, jpeg = cv2.imencode('.jpg', image)
May 21 11:07:07 raspberrypi uwsgi[428]: cv2.error: OpenCV(4.5.2) /home/pi/opencv/modules/imgcodecs/src/loadsave.cpp:896: error: $
May 21 11:07:07 raspberrypi uwsgi[428]: [pid: 562|app: 0|req: 3/5] 192.168.178.43 () {42 vars in 761 bytes} [Fri May 21 09:07:05$
-
系统中可见摄像头:
bcm2835-codec-decode (platform:bcm2835-codec):
/dev/video10
/dev/video11
/dev/video12
bcm2835-isp (platform:bcm2835-isp):
/dev/video13
/dev/video14
/dev/video15
/dev/video16
C922 Pro Stream Webcam (usb-0000:01:00.0-1.3):
/dev/video0
/dev/video1
-
项目目录的权限:
drwxr-xr-x 11 pi video 4096 May 16 19:49 HomeGuard
-
当我使用“subprocess”模块运行shell命令“v4l2 ctl--list devices”时,我得到:
CompletedProcess(args=['v4l2-ctl', '--list-devices'], returncode=1, stdout=b'', stderr=b'Failed to open /dev/video0: Permission denied\n')
所以它必须是有权限的东西。