在 spyder 中导入、编辑和显示视频,python? (替代 cv2.imshow?)
Importing, editing, and displaying videos in spyder, python? (alternative to cv2.imshow?)
我正在制作一个脚本,您可以在其中读取视频文件并检测和跟踪对象运动。我松散地遵循这种方法:https://pyimagesearch.com/2015/05/25/basic-motion-detection-and-tracking-with-python-and-opencv/
但是,我不想 运行 来自命令 window 的代码,我希望它在 spyder 中工作。这是一个问题,因为在代码的末尾,它使用 cv2.imshow(frame) 命令显示完成的视频,由于某种原因它立即使 spyder 崩溃。为了解决这个问题,我尝试改用 matplotlib,但我无法让帧在一个 window 中相互替换(即将帧放回一起再次形成视频)。
这是我使用的代码:
def cv2_imshow(a, **kwargs):
a = a.clip(0, 255).astype('uint8')
# cv2 stores colors as BGR; convert to RGB
if a.ndim == 3:
if a.shape[2] == 4:
a = cv2.cvtColor(a, cv2.COLOR_BGRA2RGBA)
else:
a = cv2.cvtColor(a, cv2.COLOR_BGR2RGB)
return plt.imshow(a, **kwargs)
get_ipython().run_line_magic('matplotlib', 'qt')
plt.ion()
cv2_imshow(frame)
我最终得到的基本上是为整个屏幕上的每一帧创建一个新的 window(即它不是一个视频 window)
有没有人有办法做到这一点?
基本上我希望这个过程是这样的:读取视频 --> 检测运动,创建带阈值的帧和带红色框中移动对象的帧 --> 重复所有帧,创建 3 个视频(甚至只是完成带有移动检测的视频)
根据,无法在 Spyder 中更新“内联图”。
我找到的壁橱解决方案是使用 clear_output
,如 this post 中所述。
代码示例:
import cv2
import numpy as np
import matplotlib.pyplot as plt
from IPython.display import clear_output
width, height, n_frames, fps = 320, 240, 10, 1
def cv2_imshow(a, **kwargs):
a = a.clip(0, 255).astype('uint8')
# cv2 stores colors as BGR; convert to RGB
if a.ndim == 3:
if a.shape[2] == 4:
a = cv2.cvtColor(a, cv2.COLOR_BGRA2RGBA)
else:
a = cv2.cvtColor(a, cv2.COLOR_BGR2RGB)
# https://matplotlib.org/stable/gallery/showcase/mandelbrot.html#sphx-glr-gallery-showcase-mandelbrot-py
dpi = 72
width, height = a.shape[1], a.shape[0]
fig = plt.figure(figsize=(width/dpi, height/dpi), dpi=dpi) # Create new figure
ax = fig.add_axes([0, 0, 1, 1], frameon=False, aspect=1) # Add axes to figure
ax.imshow(a, **kwargs)
plt.axis('off')
plt.show(block=False) # Show image without "blocking"
def make_image(i):
""" Build synthetic BGR image for testing """
p = width//60
im = np.full((height, width, 3), 60, np.uint8)
cv2.putText(im, str(i+1), (width//2-p*10*len(str(i+1)), height//2+p*10), cv2.FONT_HERSHEY_DUPLEX, p, (255, 30, 30), p*2) # Blue number
return im
# Show synthetic images in a loop
for i in range(n_frames):
a = make_image(i)
cv2_imshow(a)
plt.pause(1/fps)
#
clear_output(wait=False)
我正在制作一个脚本,您可以在其中读取视频文件并检测和跟踪对象运动。我松散地遵循这种方法:https://pyimagesearch.com/2015/05/25/basic-motion-detection-and-tracking-with-python-and-opencv/
但是,我不想 运行 来自命令 window 的代码,我希望它在 spyder 中工作。这是一个问题,因为在代码的末尾,它使用 cv2.imshow(frame) 命令显示完成的视频,由于某种原因它立即使 spyder 崩溃。为了解决这个问题,我尝试改用 matplotlib,但我无法让帧在一个 window 中相互替换(即将帧放回一起再次形成视频)。
这是我使用的代码:
def cv2_imshow(a, **kwargs):
a = a.clip(0, 255).astype('uint8')
# cv2 stores colors as BGR; convert to RGB
if a.ndim == 3:
if a.shape[2] == 4:
a = cv2.cvtColor(a, cv2.COLOR_BGRA2RGBA)
else:
a = cv2.cvtColor(a, cv2.COLOR_BGR2RGB)
return plt.imshow(a, **kwargs)
get_ipython().run_line_magic('matplotlib', 'qt')
plt.ion()
cv2_imshow(frame)
我最终得到的基本上是为整个屏幕上的每一帧创建一个新的 window(即它不是一个视频 window)
有没有人有办法做到这一点?
基本上我希望这个过程是这样的:读取视频 --> 检测运动,创建带阈值的帧和带红色框中移动对象的帧 --> 重复所有帧,创建 3 个视频(甚至只是完成带有移动检测的视频)
根据
我找到的壁橱解决方案是使用 clear_output
,如 this post 中所述。
代码示例:
import cv2
import numpy as np
import matplotlib.pyplot as plt
from IPython.display import clear_output
width, height, n_frames, fps = 320, 240, 10, 1
def cv2_imshow(a, **kwargs):
a = a.clip(0, 255).astype('uint8')
# cv2 stores colors as BGR; convert to RGB
if a.ndim == 3:
if a.shape[2] == 4:
a = cv2.cvtColor(a, cv2.COLOR_BGRA2RGBA)
else:
a = cv2.cvtColor(a, cv2.COLOR_BGR2RGB)
# https://matplotlib.org/stable/gallery/showcase/mandelbrot.html#sphx-glr-gallery-showcase-mandelbrot-py
dpi = 72
width, height = a.shape[1], a.shape[0]
fig = plt.figure(figsize=(width/dpi, height/dpi), dpi=dpi) # Create new figure
ax = fig.add_axes([0, 0, 1, 1], frameon=False, aspect=1) # Add axes to figure
ax.imshow(a, **kwargs)
plt.axis('off')
plt.show(block=False) # Show image without "blocking"
def make_image(i):
""" Build synthetic BGR image for testing """
p = width//60
im = np.full((height, width, 3), 60, np.uint8)
cv2.putText(im, str(i+1), (width//2-p*10*len(str(i+1)), height//2+p*10), cv2.FONT_HERSHEY_DUPLEX, p, (255, 30, 30), p*2) # Blue number
return im
# Show synthetic images in a loop
for i in range(n_frames):
a = make_image(i)
cv2_imshow(a)
plt.pause(1/fps)
#
clear_output(wait=False)