最近在做图像处理和标注类的学习和应用,在学习过程中遇到过暂停和播放后崩溃等问题,以下为参考解决方法
调用库:tkinter、cv2、PIL
环境:pycharm
解释器:Python3.9
只播放的实现代码:
暂停和其他控件请见完整代码
原理:将视频传入程序中转换成图片通过不断刷新Label实现视频播放
def video_play():
wait_time = 1000 / 60 #60FPS
while video.isOpened():
ret, frame = video.read()
if ret:
img = cv2.cvtColor(frame, cv2.COLOR_BGR2RGBA)
# 转换颜色使播放时保持原有色彩
current_image = Image.fromarray(img).resize((512, 384))
# 将图像转换成Image对象
imgtk = ImageTk.PhotoImage(image=current_image)
movieLabel.imgtk = imgtk
movieLabel.config(image=imgtk)
movieLabel.update()
#刷新界面
cv2.waitKey(int(wait_time))
#实现帧数固定
else:
break
#构建窗口
root = Tk()
movieLabel = Label(root, padx=253, pady=183)
movieLabel.place(x=542, y=70)
video = cv2.VideoCapture(videoAddress) #输入要播放视频的地址替换这里的videoAddress
video_play()
mainloop()
完整代码:播放/暂停视频和窗口构架(窗口只展示了与视频相关功能)
使用流程:输入本地视频地址>>确认>>开始/暂停>>播放完成>>更换地址或点击确认再次播放
暂停功能是设置key来截断video_play但不改变内存中视频地址和播放位置以达到在重新开始视频时从原位置开始
from tkinter import *
import cv2
from PIL import ImageTk, Image
key = 0
def video_play():
global key
wait_time = 1000 / 60 #设置帧率 这里设置的是60帧
while video.isOpened():
ret, frame = video.read()
if ret and key != 0:
img = cv2.cvtColor(frame, cv2.COLOR_BGR2RGBA)
# 转换颜色使播放时保持原有色彩
current_image = Image.fromarray(img).resize((512, 384))
# 将图像转换成Image对象
imgtk = ImageTk.PhotoImage(image=current_image)
movieLabel.imgtk = imgtk
movieLabel.config(image=imgtk)
movieLabel.update()
#刷线界面达到播放效果
cv2.waitKey(int(wait_time))
#利用等待实现固定帧
else:
break
#构架窗口
root = Tk()
root.resizable(False, False)
root.title('视频播放')
screenwidth = root.winfo_screenwidth()
screenheight = root.winfo_screenheight()
width = 1068
height = 681
size_root = '%dx%d+%d+%d' % (width, height, (screenwidth - width) / 2, (screenheight - height) / 2 - 70)
root.geometry(size_root)
root["background"] = "#C9C9C9"
movieLabel = Label(root, padx=253, pady=183)
movieLabel.place(x=542, y=70)
text_label = Label(root, text="视频标注", font=("微软雅黑", 24))
text_label.place(x=180, y=40)
label0 = Label(root, text="视频地址:", font=("微软雅黑", 12))
label0.place(x=60, y=150)
AddressEntry = Entry(root, width=30)
AddressEntry.place(x=150, y=153)
def confirm_action():
global video
global key
video = cv2.VideoCapture(AddressEntry.get())
key = 1
video_play()
confirmButton = Button(root, text="确认", command=confirm_action, width=6)
confirmButton.place(x=400, y=150)
def startAndPause_action():
global key
if key == 0:
key = 1
video_play()
else:
key = 0
CtrlButton = Button(root, text="开始/暂停", command=startAndPause_action)
CtrlButton.place(x=542, y=500)
mainloop()
#循环窗口
界面效果:
以上为本人在学习和实践过程中所完成如有改进或考虑不周的地方还请多多指点
谢谢观看