65.9K
CodeProject 正在变化。 阅读更多。
Home

使用 OpenCV 和 Tkinter 处理视频帧。

starIconstarIconstarIconstarIconstarIcon

5.00/5 (3投票s)

2024年4月25日

CPOL

2分钟阅读

viewsIcon

5307

downloadIcon

245

本文演示了 Python 的 OpenCV 库的一些功能。

 

引言

在本文中,我将 OpenCV 功能嵌入到使用 Tkinter 的图形应用程序中。 应用程序的用户需要指定视频文件名,可以从中提取帧。 视频的每一帧都可以作为标签中的图像显示。

背景

本文的基本思想非常简单,就是提取帧并以你喜欢的方式处理它们。 提取的帧将以“.jpg”图像的形式存储在当前文件夹内的临时子文件夹中。 可以访问并在图像标签中显示这些图像。 如果需要,也可以直接播放视频文件,而无需提取帧。

可以使用 VideoCapture(filename) 打开视频文件。 isOpened() 函数在文件成功打开时返回 truenamedWindow() 方法创建一个具有指定名称和大小的窗口,可以使用 resizeWindow() 方法将其调整为所需大小。 可以使用 read() 方法读取视频文件,该方法返回一个 boolean 值和从文件中读取的帧。 可以使用 imshow() 方法显示帧。 waitKey() 方法以指定的毫秒数显示帧。 可以使用 release() 方法关闭视频文件。 destroyAllWindows() 方法销毁所有打开的窗口。

该应用程序包含一个用于接受视频文件名的输入字段。 可以通过单击 浏览 按钮调出的打开文件对话框来选择文件名。 可以通过单击 播放 按钮直接播放视频文件。 可以通过单击 提取帧 按钮将视频中的帧提取并插入到带有顺序名称的列表框中,以及添加到列表对象中。 可以单击列表框中的帧名称以显示该帧。

使用代码

首先创建一个虚拟环境并在 OS 提示符下安装软件包,如下所示

C:\Python>python -m venv cv
C:\Python>cv\scripts\activate
(cv) C:\Python>pip install opencv-python
(cv) C:\Python>pip install pillow

以下是单击 播放 按钮时调用的 playfile() 函数

def playfile():
     filename = entfilename.get()
     if len(filename.strip()) == 0:
         lblerror.configure(text="No video file specified.")
     else:
         video = cv2.VideoCapture(filename)
         if not video.isOpened():
             lblerror.configure(text="Cannot play file " + filename + ".")
         else:
             cv2.namedWindow("Frame", cv2.WINDOW_NORMAL)
             cv2.resizeWindow("Frame", (640, 480))
             while video.isOpened():
                 ret,frame = video.read()
                 if ret:
                     cv2.imshow("Frame",frame)
                     key = cv2.waitKey(20)
                     if key == ord('q'):
                         break
                 else:
                     break
             video.release()
             cv2.destroyAllWindows()

以下是单击 提取帧 按钮时调用的 extractframes() 函数

def extractframes():
     lstframes.delete(0,"end")
     frames.clear()
     lblerror.configure(text="")
     lblimg.configure(image=None)
     lblimg.image = None
     filename = entfilename.get()
     if len(filename.strip()) == 0:
         lblerror.configure(text="No video file specified.")
     else:
         video = cv2.VideoCapture(filename)
         if not video.isOpened():
             lblerror.configure(text="Cannot open file " + filename + ".")
         else:
             i = 1
             while video.isOpened():
                 ret,frame = video.read()
                 if ret:
                     lstframes.insert("end","Frame"+str(i))
                     frames.append(frame)
                     i += 1
                 else:
                     break
             video.release()
             cv2.destroyAllWindows()

以下是选择列表框中的帧时调用的 showframe() 函数

def showframe(event):
    if not os.path.exists("temp"):
        os.mkdir("temp")
    lst = event.widget.curselection()
    if lst:
        index = lst[0]
        cv2.imwrite("temp/Frame"+str(index+1)+".jpg",frames[index])
        img = ImageTk.PhotoImage(Image.open("temp/Frame"+str(index+1)+".jpg"))
        lblimg.configure(image=img)
        lblimg.image = img

以下是单击 浏览 按钮时调用的 openfile() 函数

def openfile():
     f = fd.askopenfilename()
     entfilename.delete(0,"end")
     entfilename.insert(0,f)

以下是单击 清除 按钮时调用的 clearfile() 函数

def clearfile():
     entfilename.delete(0,"end")
     lstframes.delete(0,"end")
     frames.clear()
     lblerror.configure(text="")
     lblimg.configure(image=None)
     lblimg.image = None

关注点

读者可以下载附带的源代码文件以获取程序的完整源代码。 本文旨在突出 OpenCV 库的一个小功能。 我希望它能引导读者探索更多功能。

© . All rights reserved.