python、cv2.imshow()、树莓派和黑屏

python, cv2.imshow(), raspberryPi and a black screen

目前正在尝试使用 GUI 编写代码,这将允许切换 on/off 图像处理。理想情况下,代码将允许转换 on/off window 视图、实时图像处理(非常基本)和控制外部板。

我遇到的问题与 cv2.imshow() 函数有关。几个月前,我通过从 picamera 切换到 cv2 来推动提高处理速度,这样我就可以执行更复杂的计算,例如背景减法,而不必一直调用 python。使用 bcm2835-v4l2 包,我可以使用 cv2.

直接从 picamera 中提取图像

快进 6 个月,在尝试更新代码时,我发现函数 cv2.imshow() 不再正确显示。我认为这可能是 bcm2835-v4l2 的问题,但使用 matplotlib 的测试表明连接正常。我猜它似乎与 cv2.imshow() 有关。

我实际上是在使用 threading 模块创建一个单独的线程来捕获图像,我想知道这是否是罪魁祸首。我不这么认为,尽管输入命令

import cv2
camera = cv2.VideoCapture(0)
grabbed,frame = camera.read()
cv2.imshow(frame)

产生相同的黑屏

下面是我正在使用的代码(在 RPi3 上),一些图像显示了错误和预期的结果。

至于参考这里是关于我的系统的详细信息

Raspberry pi3
raspi stretch
python 3.5.1
opencv 3.4.1

代码

import cv2
from threading import Thread
import time
import numpy as np
from tkinter import Button, Label, mainloop, Tk, RIGHT

class GPIOControllersystem:
    def __init__(self,OutPinOne=22, OutPinTwo=27,Objsize=30,src=0):
        self.Objectsize = Objsize

        # Build GUI controller
        self.TK = Tk()                                                          # Place TK GUI class into self

        # Variables
        self.STSP = 0
        self.ShutdownVar = 0
        self.Abut = []
        self.Bbut = []
        self.Cbut = []
        self.Dbut = []

        # setup pi camera for aquisition
        self.resolution = (640,480)
        self.framerate = 60

        # Video capture parameters
        (w,h) = self.resolution
        self.bytesPerFrame = w * h

        self.Camera = cv2.VideoCapture(src)
        self.fgbg = cv2.createBackgroundSubtractorMOG2()

    def Testpins(self):
        while True:
            grabbed,frame = self.Camera.read()
            frame = self.fgbg.apply(frame)

            if self.ShutdownVar ==1:
                break
            if self.STSP == 1:
                pic1, pic2 = map(np.copy,(frame,frame))
                pic1[pic1 > 126] = 255
                pic2[pic2 <250] = 0
                frame = pic1
            elif self.STSP ==1:
                time.sleep(1)
            cv2.imshow("Window",frame)
        cv2.destroyAllWindows()

    def MProcessing(self):
        Thread(target=self.Testpins,args=()).start()
        return self

    def BuildGUI(self):
        self.Abut = Button(self.TK,text = "Start/Stop System",command = self.CallbackSTSP)
        self.Bbut = Button(self.TK,text = "Change Pump Speed",command = self.CallbackShutdown)
        self.Cbut = Button(self.TK,text = "Shutdown System",command = self.callbackPumpSpeed)
        self.Dbut = Button(self.TK,text = "Start System",command = self.MProcessing)

        self.Abut.pack(padx=5,pady=10,side=RIGHT)
        self.Bbut.pack(padx=5,pady=10,side=RIGHT)
        self.Cbut.pack(padx=5,pady=10,side=RIGHT)
        self.Dbut.pack(padx=5,pady=10,side=RIGHT)
        Label(self.TK, text="Controller").pack(padx=5, pady=10, side=RIGHT)
        mainloop()

    def CallbackSTSP(self):
        if self.STSP == 1:
            self.STSP = 0
            print("stop")
        elif self.STSP == 0:
            self.STSP = 1
            print("start")

    def CallbackShutdown(self):
        self.ShutdownVar = 1

    def callbackPumpSpeed(self):
        pass

if __name__ == "__main__":
    GPIOControllersystem().BuildGUI()

使用matplotlib.pyplot.imshow(),我可以看到raspberry pi相机和opencv之间的连接是通过bcm2835-v4l2连接工作的。

然而,当使用 opencv.imshow() 时,window 会导致黑框,不显示任何内容。

更新:所以在测试时我发现当我执行以下任务时

import cv2
import matplotlib

camera = cv2.VideoCapture(0)
grab,frame = camera.read()
matplotlib.pyplot.imshow(frame)

grab,frame = camera.read()
matplotlib.pyplot.imshow(frame)

更新已解决,与主要问题无关。这是一个缓冲问题。似乎与 cv2.imshow()

无关

在你应该使用的覆盆子上 从 picamera 导入 PiCamera 结账 pyimagesearch