对于我的图像处理算法,我使用的是python / OpenCV。我的算法输出应该在同一个窗口一遍又一遍地更新。
然而,有时窗口会冻结并且根本不会更新,但算法仍然在运行并同时多次更新图片。在这台Ubuntu机器上,窗口变成深灰色。
以下是相关代码的摘录:
for i in range(0,1000):
img = loadNextImg()
procImg = processImg(img)
cv2.imshow("The result", procImg)
cv2.waitKey(1)
N.B。:processImg()程序大约需要1-2秒。第cv2.imshow(procImg)
行在第一个实例中创建窗口(即没有先前的调用)
答案 0 :(得分:5)
我的建议是使用Matplotlib pyplot来显示图像。我是按照以下方式做的。
import matplotlib.pyplot as plt
# load image using cv2....and do processing.
plt.imshow(cv2.cvtColor(image, cv2.BGR2RGB))
# as opencv loads in BGR format by default, we want to show it in RGB.
plt.show()
我知道它不能解决cv2.imshow的问题,但它解决了我们的问题。
答案 1 :(得分:4)
增加等待时间可以解决此问题。但是在我看来,这是不必要的睡眠时间(20毫秒/帧),即使它并不多。
更改
cv2.waitKey(1)
到
cv2.waitKey(20)
防止窗口在我的情况下冻结。所需的等待时间可能因机器而异。
答案 2 :(得分:3)
我有同样的问题,我注意到窗口更新的fps越来越慢,直到它完全冻结。 将waitKey(x)增加到更高的值只会延长图像更新的持续时间,但是当cv2.imshow()需要计算的时间超过等待时间(Key)时,它就会停止更新。
(跳过这个抱怨:) 我认为带有waitKey()组合的cv2.imshow()是一个完整的设计错误,为什么imshow()只是阻塞直到UI更新?这将使生活变得如此简单,而不必每次都调用waitKey()......
P.S。:有可能为opencv中的opencv窗口启动一个自己的线程:
import cv2
img = cv2.imread("image.jpg")
cv2.startWindowThread()
cv2.namedWindow("preview")
cv2.imshow("preview", img)
来源:cv2.imshow command doesn't work properly in opencv-python
这对我不起作用,因为我在运行它时总会出现这个错误:
(python3:1177): GLib-GObject-CRITICAL **: g_object_unref: assertion 'G_IS_OBJECT (object)' failed
Attempt to unlock mutex that was not locked
Aborted
也许您可以尝试并报告它是否适合您?
修改强> 好吧,我通过创建一个单独的脚本imshow.py解决了这个问题:
import cv2
import os.path
while True:
if os.path.exists("image.pgm"):
image = cv2.imread("image.pgm")
if not image is None and len(image) > 0:
cv2.imshow("Frame", image)
cv2.waitKey(20)
我正在我的其他程序中写出图像:cv2.imwrite("image.pgm", image)
我正在调用这样的脚本:
import subprocess
subprocess.Popen(["python3", "imshow.py"])
虽然这有时会创建一些脏读取对我来说足够了,但更好的解决方案是在两个进程之间使用管道或队列。
答案 3 :(得分:2)
只需在cv2.destroyAllWindows()
之后添加cv2.waitKey()
答案 4 :(得分:1)
所以我认为这里发生的是,在第一次调用imshow之后仍然处于活动状态的窗口(highGUI的一个元素)正在等待来自waitKey函数的某种响应,但是变为非活动状态因为程序卡在loadIxtImg函数的processImg中。如果你不关心效率的轻微浪费(即你没有在每个操作都很重要的嵌入式系统上运行),你应该在waitKey之后销毁窗口,并在imshow之前重新创建。由于在处理和加载图像期间窗口不再存在,因此highGUI不会等待来自waitKey的调用,并且不会无响应。
答案 5 :(得分:1)
try:
import cv2
except:
print("You need to install Opencv \n Run this command \n pip install python-opencv")
exit()
print('Press q to quit frame')
def viewer(name,frame):
while True:
cv2.imshow(name,frame)
if cv2.waitKey(10) & 0xff ==ord('q'):
break
return
cv2.destroyWindow(name)
保存该程序,然后从现在开始,导入它并使用功能查看器显示任何框架/图像,并且显示窗口不会挂起或崩溃。
答案 6 :(得分:0)
如果您的窗口变灰,则可能需要更多处理能力。因此,尝试将图像调整为较小尺寸的图像并执行。有时候,由于在执行操作时按任意键,它在ipython笔记本中运行时会冻结。我亲自处理了你的问题,但是在做这件事时我并没有得到灰色屏幕。我直接使用终端执行。代码和步骤如下所示。
import argparse
import cv2
import numpy as np
# construct the argument parser and parse the arguments
ap = argparse.ArgumentParser()
ap.add_argument("-i", "--image", required=True, help="Path to the image")
args = vars(ap.parse_args())
# load the image, grab its dimensions, and show it
image = cv2.imread(args["image"])
(h, w) = image.shape[:2]
cv2.imshow("Original", image)
cv2.waitKey(0)
for i in range(0,1000):
image = cv2.imread(args["image"])
cv2.imshow("The result",image);
cv2.waitKey(0)
在终端中运行:
这将只在一个窗口中显示您的结果(每次更新)而不冻结,如果您想在每个新窗口中显示单独的图像,请添加.format(i),如下所示。但是请记住只在终端中运行而不是在jupyter笔记本中运行。
您可以在此视频链接中使用终端命令进行检查 https://www.youtube.com/watch?v=8O-FW4Wm10s
for i in range(0,1000):
image = cv2.imread(args["image"])
cv2.imshow("The result{}".format(i),image);
cv2.waitKey(0)
这可能有助于分别为您提供1000张图像。
答案 7 :(得分:0)
在cv2.imshow()
函数之后添加以下两行代码,
cv2.waitKey()
cv2.destroyAllWindows()
答案 8 :(得分:0)
您可以使用while循环来拍摄连拍图像而不会冻结。这是拍摄10张图像的示例。您还可以尝试在while循环中增加waitkey
的数量和sleep
的时间。这对我有用。
key = cv2.waitKey(1)
webcam = cv2.VideoCapture(0)
sleep(1)
while True:
try:
check, frame = webcam.read()
cv2.imshow("Capturing", frame)
key = cv2.waitKey(1)
img_counter = 0
if key & 0xFF == ord('s'): #press s to take images
while img_counter < 10:
check, frame = webcam.read()
cv2.imshow("Capturing", frame)
key = cv2.waitKey(1)
path = 'F:/Projects/' #folder path to save burst images
img_name = "burst_{}.png".format(img_counter)
cv2.imwrite(os.path.join(path, img_name), img=frame)
print("Processing image...")
img_ = cv2.imread(img_name, cv2.IMREAD_ANYCOLOR) #save as RGB color format
print("{} written!".format(img_name))
img_counter += 1
sleep(0.2)
webcam.release()
cv2.destroyAllWindows()
break
elif key == ord('q'): #press q to quit without taking images
webcam.release()
cv2.destroyAllWindows()
break
except(KeyboardInterrupt):
print("Turning off camera.")
webcam.release()
print("Camera off.")
print("Program ended.")
cv2.destroyAllWindows()
break