Opencv imshow()在更新时冻结

时间:2016-05-04 21:45:07

标签: python opencv image-processing freeze imshow

对于我的图像处理算法,我使用的是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)行在第一个实例中创建窗口(即没有先前的调用)

9 个答案:

答案 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)

在终端中运行:

  1. source activate env_name
  2. python Filename.py --image Imagename.png
  3. 这将只在一个窗口中显示您的结果(每次更新)而不冻结,如果您想在每个新窗口中显示单独的图像,请添加.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