Raspberrypi Python显示内存中的图像

时间:2018-12-27 14:41:50

标签: python image camera raspberry-pi

任务正在执行:在外部事件(GPIO)上从Picamera捕获帧并将其显示在屏幕上。

使用的方法:

  1. PIL image.show()-制作临时文件并使用外部查看器,我需要从内存中获取。

  2. Opencv cv.imshow()-几次序列化事件后冻结带有图像的窗口。我玩了一段时间,它仍然冻结。

  3. UPD:带有图像的Gdk窗口在多个事件后也会冻结,但是如果GLib计时器事件调用更新而不是GPIO的处理程序,则不会冻结。

您能提出建议完成此任务的任何方法吗?

1 个答案:

答案 0 :(得分:0)

创建一个小巧的RAMdisk,既美观又快速,并避免SD卡磨损。将图像写入该图像并使用feh或类似的图像进行显示:

sudo mkdir -p /media/ramdisk
sudo mount -t tmpfs -o size=4M tmpfs /media/ramdisk

df /media/ramdisk
Filesystem     1K-blocks  Used Available Use% Mounted on
tmpfs               4096     0      4096   0% /media/ramdisk

然后启动Python脚本更新您的图像。


初始脚本可能如下所示:

#!/bin/bash

# Create a couple of useful variables
MNTPNT="/media/ramdisk"
IMGNAM="$MNTPNT/image.ppm"

# Make ramdisk and mount
sudo mkdir -p /media/ramdisk 2> /dev/null
sudo mount -t tmpfs -o size=4M tmpfs /media/ramdisk 2> /dev/null

# Create initial empty image to display with ImageMagick or any other means
convert -size 800x600 xc:black -depth 8 "$IMGNAM"

# Get 'feh' started in "Slideshow mode" in the background
feh --title "Monitor" -D 0.5 "$IMGNAM" "$IMGNAM" &

# Now start Python script with image name
./monitor.py "$IMGNAM"

然后,Python脚本monitor.py可能看起来像这样:

#!/usr/bin/python3

import os, sys, time
from PIL import Image, ImageDraw
from random import randint

# Pick up parameters
filename = sys.argv[1]

# Create initial image and drawing handle
w, h = 800, 600
im = Image.new("RGB",(w,h),color=(0,0,0))
draw = ImageDraw.Draw(im)

# Create name of temp image in same directory
tmpnam = os.path.join(os.path.dirname(filename), "tmp.ppm") 

# Now loop, updating the image 100 times
for i in range(100):
   # Select random top-left and bottom-right corners for image
   x0 = randint(0,w)
   y0 = randint(0,h)
   x1 = x0 + randint(10,250)
   y1 = y0 + randint(10,250)
   # Select a random colour and draw a rectangle
   fill = (randint(0,255), randint(0,255), randint(0,255))
   draw.rectangle([(x0,y0),(x1,y1)], fill=fill)
   # Save image to a temporary file, then rename in one immutable operation...
   # ... so that 'feh' cannot read a half-saved image
   im.save(tmpnam)
   os.rename(tmpnam,filename)
   time.sleep(0.3)

enter image description here

本质上,您的应用程序要做的就是:

 while true:
   ... generate new image ...
   im.save(tmpnam)
   os.rename(tmpnam,filename)

如果从--title "monitor"命令中删除feh,您将看到它只是遍历2张图像的列表,而这2张图像恰好是同一张图像。图像每0.5秒交换一次,而不闪烁。您可以根据需要进行更改。如果您由于某种原因不希望它在两者之间连续交替,您可以使延迟更大,并向SIGUSR1feh)发送os.kill(pid, signal.SIGUSR1)到任何时候切换更新图像。