效果
python代码
import cv2,os
import tkinter as tk
from tkinter import filedialog
from PIL import ImageTk,Image
class Display():
def __init__(self,wide=800, height=500,save_path="result",fps=70):
self.W, self.H = wide, height
self.fps=fps
self.save_path = save_path
self.button_w, self.button_h = 100, 30
self.button_hstretch=10
self.button_wstretch = 10
self.video_cap=None
self.frame=None
self._init_root()
def run(self):
self.root.mainloop()
def _init_root(self,):
self.root=tk.Tk()
self.root.title("video shot")
self.root.config(background="white")
self.root.geometry(str(self.W) + "x" + str(self.H) + "-500-200")
self.root.resizable(0, 0)
self.root.attributes("-alpha", 0.95)
"""left area"""
self.video_w, self.video_h= int(3 / 4 * self.W) - 1, int(self.H) - 2
self.video_area = tk.Label(self.root, bg="black", fg="green", cursor="cross")
self.video_area.place(x=1, y=1, w=self.video_w, h=self.video_h - 35)
self.text_area_frame = tk.Label(self.root, text="----------------")
self.text_area_frame.place(x=1, y=self.video_h - 32, w=120, h=30)
self.text_area_info = tk.Label(self.root, text="----------------")
self.text_area_info.place(x=130, y=self.video_h - 32, w=self.video_w-130, h=30)
"""right area"""
right_x, right_y = 7 / 8 * self.W - 1 / 2 * self.button_w, 3 / 11 * self.H
tk.Button(self.root, text="选择文件", relief="groove", command=self._select_video)\
.place(x=right_x, y= right_y-20, w=self.button_w, h=self.button_h)
tk.Button(self.root, text="播放", relief="groove", command=self._play)\
.place(x=right_x, y= right_y+2*self.button_h+self.button_hstretch, w=self.button_w, h=self.button_h)
tk.Button(self.root, text=" 截屏", relief="groove", command=self._screen_shot)\
.place(x=right_x, y= right_y+4*(self.button_h+self.button_hstretch), w=self.button_w, h=self.button_h)
tk.Button(self.root, text="关闭", relief="groove", command=self._exit)\
.place(x=right_x, y= right_y+6*(self.button_h+self.button_hstretch), w=self.button_w, h=self.button_h)
def _select_video(self):
self.video_file=filedialog.askopenfilename()
def _play(self):
self.video_cap = cv2.VideoCapture(self.video_file)
frame_count=self.video_cap.get(cv2.CAP_PROP_FRAME_COUNT)
video_source=self._get_frame(self.video_cap,self.fps)
self.count=0
for self.frame in video_source:
img=self._convert_img(self.frame, self.video_w)
self.video_area.config(image=img)
self.video_area.update()
self.text_area_frame.config(text='frame: ' + str(self.count) + " /:" + str(frame_count))
self.text_area_frame.update()
self.count+=1
self.video_cap.release()
def _screen_shot(self):
os.makedirs(self.save_path, exist_ok=True)
name = self.video_file.split(".")[0].split("/") [-1]
cv2.imwrite(os.path.join(self.save_path, name + "_" + str(self.count) + '.bmp'), self.frame)
self.text_area_info.config(text='save frame to: ' +
os.path.join(self.save_path, name + "_" + str(self.count) + '.bmp'))
self.text_area_info.update()
def _get_frame(self,video_cap, fps=70):
while 1:
ret, frame = video_cap.read()
if cv2.waitKey(int(1000 / fps)) == 27 or not ret:
break
yield frame
def _convert_img(self,img,video_w):
h, w, _ = img.shape
wc ,hc= video_w,int(h * (video_w / w))
img=cv2.cvtColor(img,cv2.COLOR_BGR2RGB)
current_image = Image.fromarray(img, "RGB").resize((wc, hc), Image.ANTIALIAS)
img = ImageTk.PhotoImage(image=current_image)
return img
def _exit(self):
self.video_cap.release()
exit()
if __name__=="__main__":
ds=Display()
ds.run()
附1.0版本,按一定帧间隔保存
def getPic(file, interval, save_path="result", fps=70):
"""
视屏截图
:param file:
:param interval:按指定间隔保存
:param save_path:
:param fps:
"""
os.makedirs(save_path,exist_ok=True)
name=file.split(".")[0]
video = cv2.VideoCapture(file)
cv2.namedWindow(file, 0)
count=0
while 1:
ret, frame = video.read()
if cv2.waitKey(int(1000/fps)) == 27 or not ret:
break
if count % interval == 0:
cv2.imwrite(os.path.join(save_path ,name+"_"+ str(count//interval) + '.bmp'), frame)
cv2.putText(frame, "cut"+str(count//interval), (123, 456),
cv2.FONT_HERSHEY_SIMPLEX, 2, (0, 255, 0), 3)
cv2.imshow(file, frame)
count+=1
video.release()
cv2.destroyAllWindows()
if __name__=="__main__":
getPic(file="view1.mp4", interval=50, fps=70)