使用matplotlib重现OpenCV imshow()和waitKey()

Anj*_*jou 0 python opencv matplotlib

以下代码在Windows上运行良好,但我需要在Ubuntu上运行它,似乎cv2.imshow()不支持.我正在寻找使用matplotlib在Ubuntu上运行的任何其他库的替代方案.

它的工作原理如下:

我有一个框架列表,一个框架是一个numpy代表RGB图像的数组.我循环通过框架,显示当前的框架cv2.imshow()并使用waitKey()注册动作,保留框架(将其附加到另一个列表)或解除它.我需要将图像显示在与其他窗口相同的窗口中.

代码 :

"""
    frames is a list of 3-d numpy array representing an RGB image.
"""
keeped_frames = []
frame_index = 0
frames_upper_bound = len(frames)
for frame in frames:
    print('Showing frame {} / {}'.format(frame_index + 1,frames_upper_bound))
    cv2.imshow('frame', frame)
    key = cv2.waitKey(0) & 0xFF
    if key == ord('0'):
        print('Not appending frame {} / {} to list'.format(frame_index + 1, frames_upper_bound))
    elif key == ord('1'):
        print('Appending frame {} / {} to list'.format(frame_index + 1, frames_upper_bound))
        keeped_frames.append(frame)
    elif key == ord('q'):
        cv2.destroyAllWindows()
        break
    frame_index += 1
Run Code Online (Sandbox Code Playgroud)

我尝试了plt.imshow()一个循环,但每次都会创建新的窗口.即使修复了这个问题,如何轻松注册键盘动作并快速切换到下一帧?由于cv2它工作得很好,我可以保持按键,框架通过相当快; 因为我需要以这种方式注释数千个帧,我想要类似的东西.

我可以使用matplotlib或在Ubuntu上运行的任何其他库来复制此行为吗?

And*_*lev 7

当然,您可以使用matplotlib 的imshow方法matplotlib.pyplot事件处理功能.您可以尝试以下代码,看看它是否适合您:

import matplotlib as mpl 
mpl.use('wxAgg')

import numpy as np 
import matplotlib.pyplot as plt

# just some random data 
frames = [np.random.random((10, 10)) for _ in range(100)]
keeped_frames = [] 
i = 0

# event listener 
def press(event):
    global i
    if event.key == '1':
        print('Appending frame')
        keeped_frames.append(frames[i % 100])
    i += 1
    imgplot.set_data(frames[i % 100])
    fig.canvas.draw()

fig, ax = plt.subplots() 
fig.canvas.mpl_connect('key_press_event', press)
imgplot = ax.imshow(frames[i % 100]) 
plt.show()
Run Code Online (Sandbox Code Playgroud)

您应该注意的一件事是,侦听器行为取决于您正在使用的后端.在Qt5Agg一个按键触发一个key_press事件是否把握关键与否,并在wxAgg钥匙保持火灾continious按下并释放事件(的行为,你的愿望,我猜).