使用 opencv 在 Python 中实现光流的问题
Posted
技术标签:
【中文标题】使用 opencv 在 Python 中实现光流的问题【英文标题】:Issues with optical flow implementation in Python using opencv 【发布时间】:2019-09-17 05:52:26 【问题描述】:我有以下简单的光流代码。这会从 gif 序列中读取前两帧,然后计算它们之间的流。
import cv2
import numpy as np
import tkinter as tk
from tkinter import filedialog
from matplotlib import pyplot as plt
root = tk.Tk()
root.withdraw()
path = filedialog.askopenfilename()
video = cv2.VideoCapture(path)
_,im1 = video.read()
im1 = cv2.cvtColor(im1, cv2.COLOR_BGR2GRAY)
success = True
while(success):
success,im2 = video.read()
if success == True:
im2 = cv2.cvtColor(im2, cv2.COLOR_BGR2GRAY)
success = False
hsv = np.zeros_like(im1)
hsv[...,1] = 255
flow = cv2.calcOpticalFlowFarneback(im1,im2, None, 0.5, 3, 15, 3, 5, 1.2, 0)
mag, ang = cv2.cartToPolar(flow[...,0], flow[...,1])
hsv[...,0] = ang*180/np.pi/2 # Error in this line
hsv[...,2] = cv2.normalize(mag,None,0,255,cv.NORM_MINMAX)
bgr = cv2.cvtColor(hsv,cv.COLOR_HSV2BGR)
cv2.imshow('frame2',bgr)
上述实现是用于计算颜色编码光流的标准 openCV 版本。但是,我在评论的行中遇到错误。这是因为如错误所示,将 (m X n) 向量分配给 (m,) 向量。
ValueError: could not broadcast input array from shape (512,512) into shape (512)
hsv[...,0].shape 给出 512 而 ang.shape 是 512 X 512
>> print(hsv[...,0].shape)
>> 512
>> print(ang.shape)
>> (512,512)
但是来自 openCV 网站的用于计算颜色编码光流的相同代码会产生一个输出,其中会弹出一个带有一些颜色流的窗口并消失,然后出现以下错误:
OpenCV Error: Assertion failed (scn == 3 || scn == 4) in cvtColor,file /build/opencv-L2vuMj/opencv-3.2.0+dfsg/modules/imgproc/src/color.cpp, line 9748
Traceback (most recent call last):
File "OF_Farneback.py", line 12, in <module>
next = cv.cvtColor(frame2,cv.COLOR_BGR2GRAY)
cv2.error: /build/opencv-L2vuMj/opencv-3.2.0+dfsg/modules/imgproc/src/color.cpp:9748: error: (-215) scn == 3 || scn == 4 in function cvtColor
我所指的代码如下:
import numpy as np
import cv2 as cv
cap = cv.VideoCapture("sampleSeq.gif")
ret, frame1 = cap.read()
prvs = cv.cvtColor(frame1,cv.COLOR_BGR2GRAY)
hsv = np.zeros_like(frame1)
hsv[...,1] = 255
while(1):
ret, frame2 = cap.read()
next = cv.cvtColor(frame2,cv.COLOR_BGR2GRAY)
flow = cv.calcOpticalFlowFarneback(prvs,next, None, 0.5, 3, 15, 3, 5, 1.2, 0)
mag, ang = cv.cartToPolar(flow[...,0], flow[...,1])
hsv[...,0] = ang*180/np.pi/2
hsv[...,2] = cv.normalize(mag,None,0,255,cv.NORM_MINMAX)
bgr = cv.cvtColor(hsv,cv.COLOR_HSV2BGR)
cv.imshow('frame2',bgr)
k = cv.waitKey(30) & 0xff
if k == 27:
break
elif k == ord('s'):
prvs = next
我的问题是:
-
为什么在第二种情况下没有出现原始错误,其中颜色编码的流显示在循环内?
如何修复第一个代码中的赋值错误?
如何修复第二个代码中的错误,我猜这主要是因为它已达到 EOF ?
任何指针,建议都会有所帮助。谢谢你。
【问题讨论】:
【参考方案1】:在您的代码中,hsv
是从im1
创建的,此时后一个矩阵是灰度矩阵,即它只有一个通道。在OpenCV 示例代码中,hsv
是从frame1
创建的,frame1
是一个颜色矩阵,即有3 个颜色通道。因此,hsv
的大小在两个代码 sn-ps 之间有所不同,我认为这是第 1 点和第 2 点的原因。
关于第 3 点,解决此问题的最简单方法是
while(1):
ret, frame2 = cap.read()
if(!ret): # ie there is no next frame
break
else:
#code as before
【讨论】:
以上是关于使用 opencv 在 Python 中实现光流的问题的主要内容,如果未能解决你的问题,请参考以下文章