使用cv2.cvtColor(frame,cv2.COLOR_BGR2GRAY)

时间:2019-11-15 12:59:14

标签: python opencv pixel video-processing

试图计算动画每一帧(白色圆圈在黑框上移动)中白色像素的数量,我遇到了这个OpenCV function

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

total_white_pixels_in_video_sequence = 0

while(cap.isOpened()):

    # Take each frame of the video.
    _, frame = cap.read()


    #print(frame)

    # Convert BGR to gray
    gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)

    print ("No. of pixels : ", gray.shape[0] * gray.shape[1])

    # Counting the number of pixels with given value: define range of gray color in HSV
    total_white_pixels_in_video_sequence += np.count_nonzero(gray == 255)

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

cap.release()
cv2.destroyAllWindows()

print ("total_white_pixels_in_video_sequence : ", total_white_pixels_in_video_sequence)

我遇到第一个错误:

  

错误:OpenCV(4.1.0)/io/opencv/modules/imgproc/src/color.cpp:182:   错误:(-215:断言失败)函数'cvtColor'中的!_src.empty()

我在这里找到了两种可能的解决方法:

  1. 我尝试了gray = cv2.cvtColor(np.float32(frame), cv2.COLOR_BGR2GRAY),但仍然出现错误:
  

TypeError:参数'src'预期的cv :: UMat

  1. 然后我尝试了gray = cv2.cvtColor(cv2.UMat(frame), cv2.COLOR_BGR2GRAY),并收到了错误消息:
  

AttributeError:'cv2.UMat'对象没有属性'shape'

当我打印框架时,我得到一个零数组:[[[[0 0 0] [0 0 0] [0 0 0] ...

我检查了路径,它在此代码的同一目录中。所以路径应该不是问题吗?

按照link的建议,我检查了视频文件的完整性,并在Linux终端ffmpeg -v error -i control_random.mp4 -f null - 2>error.log中尝试了此命令,但未打印任何内容。

我的问题:调试它是否值得,或者还有另一种计算每帧白色像素数量的方法。在创建动画时以及生成视频之前,我也可以这样做。

这段代码创建了我的动画:

for Nframes in range(8):

    with shader:  

        transformations['view_matrix'] = get_view_matrix(z=scrDist)
        transformations.send()


        for sphere in spheres:

            # Update Spheres Positions
            sphere.position.x += sphere.dx
            sphere.position.y += sphere.dy
            sphere.position.z += sphere.dz

            # Draw the spheres
            sphere.draw()

    # Get the back buffer frames
    win.getMovieFrame(buffer='back')

    win.flip()

我们非常感谢您的帮助,我们非常需要您的帮助。非常感谢!

1 个答案:

答案 0 :(得分:2)

我的猜测是您在不同时间点都有此错误,这就是令人困惑的地方。原始错误可能发生在视频结尾。

至少我们可以肯定地说,由于_, frame = cap.read()最终将返回frame = None,因此此代码将输出错误。

因此,为避免出现问题,您必须读取返回的值“ _”,并在错误的情况下将其中断(表示未获取任何帧)。

也许您使用了while循环,因为帧数有点奇怪,您必须使用:

number_of_frames = video_capture.get(cv2.CAP_PROP_FRAME_COUNT)

这允许使用常规的for循环,并在出现错误情况时保留此布尔值。 这是更新的代码,它可以与我的mp4之一配合使用。

cap = cv2.VideoCapture('control_random.mp4')
total_white_pixels_in_video_sequence = 0

if cap.isOpened():

    number_of_frames = int(cap.get(cv2.CAP_PROP_FRAME_COUNT))

    for frame_number in range(number_of_frames):
        # Take each frame of the video.
        success, frame = cap.read()

        if not success:
            raise Exception('Failed to read the frame number: {}'.format(frame_number))

        print('{} / {}'.format(frame_number, number_of_frames))

        # Convert BGR to gray
        gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)

        print("No. of pixels : ", gray.shape[0] * gray.shape[1])

        # Counting the number of pixels with given value: define range of gray color in HSV
        total_white_pixels_in_video_sequence += np.count_nonzero(gray == 255)

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

cap.release()
cv2.destroyAllWindows()

print("total_white_pixels_in_video_sequence : ", total_white_pixels_in_video_sequence)

还请注意,您可以单独测试全黑图像的转换:

gray = cv2.cvtColor(np.zeros((256,256,3), dtype=np.ubyte), cv2.COLOR_BGR2GRAY)

我认为您的试用版1.失败了,因为BGR图片是8u图片,因此它不接受浮点数。 对于试用版2,请注意,opencv通常可用于numpy数组(如上述零示例)。

希望这会有所帮助!