目前正在尝试编写带有GUI的代码,可以切换图像处理的开关。理想情况下,该代码将允许打开/关闭窗口视图、实时图像处理(相当基础)以及控制外部板子。
我遇到的问题与cv2.imshow()
函数有关。几个月前,我通过从picamera
转换到cv2
来提高处理速度,这样我就可以执行更复杂的计算,如背景减除,而不必一直调用python。使用bcm2835-v4l2包,我能够直接从picamera中使用cv2
获取图像。
快进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()
,我可以看到树莓派相机和opencv之间的连接是通过bcm2835-v4l2连接工作的。
![使用系统捕获的帧图像,但使用matplotlib绘制](https://istack.dev59.com/FHdP1.webp)
opencv.imshow()
时,窗口会显示一个黑色方框,没有任何内容显示。
![输入图像描述](https://istack.dev59.com/cvQnN.webp)
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()没有任何相关性。
frame
的 VideoCapture 是否实际返回图像数据了吗(跳过处理)?我猜如果你进一步最小化你的代码([mcve]),它将有助于你追踪根本原因。祝你好运! - handlecv2.imshow('Window",frame)
后面加上了cv2.waitKey(1)
。经过查阅资料,cv2.waitKey()
命令是显示图像所必需的。问题得到了解决。 - Hojo.Timberwolf