OpenCV中的cvtColor函数错误:断言失败(scn == 3 || scn == 4)

3

我想简单地加载一个视频文件,将其转换为灰度图像并显示出来。以下是我的代码:

import numpy as np
import cv2

cap = cv2.VideoCapture('cars.mp4')

while(cap.isOpened()):
    # Capture frame-by-frame
    ret, frame = cap.read()
    #print frame.shape   


    # Our operations on the frame come here
    gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)

    # Display the resulting frame
    cv2.imshow('frame',gray)
    if cv2.waitKey(1) & 0xFF == ord('q'):
        break


# When everything done, release the capture
cap.release()
cv2.destroyAllWindows()

视频一直以灰度播放直到结束,然后窗口卡死并显示“未响应”,终端会出现以下错误信息:
OpenCV Error: Assertion failed (scn == 3 || scn == 4) in cvtColor, file /home/clive/Downloads/OpenCV/opencv-2.4.9/modules/imgproc/src/color.cpp, line 3737
Traceback (most recent call last):
  File "cap.py", line 13, in <module>
    gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
cv2.error: /home/clive/Downloads/OpenCV/opencv-2.4.9/modules/imgproc/src/color.cpp:3737: error: (-215) scn == 3 || scn == 4 in function cvtColor

我取消注释了print frame.shape语句。它一直打印720,1028,3。但是在视频播放到结尾后,它会冻结一段时间然后关闭并返回。

print frame.shape   
AttributeError: 'NoneType' object has no attribute 'shape'

我理解这个断言失败信息通常意味着我试图转换一个空的图片。在使用if(ret):语句开始处理之前,我添加了一个检查空图片的步骤。(还有其他做法吗?)

import numpy as np
import cv2

cap = cv2.VideoCapture('cars.mp4')

while(cap.isOpened()):
    # Capture frame-by-frame
    ret, frame = cap.read()
    #print frame.shape   

    if(ret): #if cam read is successfull
        # Our operations on the frame come here
        gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)

        # Display the resulting frame
        cv2.imshow('frame',gray)
        if cv2.waitKey(1) & 0xFF == ord('q'):
            break
    else:
        break

# When everything done, release the capture
cap.release()
cv2.destroyAllWindows()

这次视频播放到最后,窗口仍然在几秒钟后冻结并关闭。这次我没有收到任何错误提示。但是为什么窗口会冻结?我该如何修复它?


也许cap.release()需要一些时间才能完成。如果你将结尾的两行代码交换,窗口是否仍然冻结? - Arnaud P
@Arnaud P 是的,它确实可以。 - Clive
好的。最后一个猜测:如果你正在进行多线程操作,opencv图像显示可能无法正常工作,除非它在主线程上运行。 - Arnaud P
@Arnaud P 什么是多线程?如何在“主线程”上运行? - Clive
维基百科上的“多线程(Multithreading)”是指并行处理。如果你运行一个“简单”的Python脚本,而且没有意识到使用了线程,那么你可能已经在主线程上运行了。但是,如果你被集成到一个框架中,这个问题就有点复杂了。 - Arnaud P
1个回答

1

waitKey()部分不应该依赖于帧的有效性,将其移出条件:

import numpy as np
import cv2

cap = cv2.VideoCapture('cars.mp4')

while(cap.isOpened()):
    # Capture frame-by-frame
    ret, frame = cap.read()
    #print frame.shape   

    if(ret): #if cam read is successfull
        # Our operations on the frame come here
        gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)

        # Display the resulting frame
        cv2.imshow('frame',gray)
    else:
        break

    # this should be called always, frame or not.
    if cv2.waitKey(1) & 0xFF == ord('q'):
        break

我尝试了你建议的方法,但仍然得到相同的结果。视频结束后窗口冻结了。 - Clive
我注意到如果“else”语句放在最后一个“if”语句之后,那么视频根本不会播放。我只看到窗口弹出并显示一帧,然后很快关闭。这发生得非常快。我猜只有一帧被播放了。为什么会这样? - Clive
因为你的代码接着写了 if 'q': break else: break,这意味着它根本无法循环。 - Arnaud P

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接