开向幼儿园的车 2022-10-03 11:48 采纳率: 81.8%
浏览 20
已结题

基于OPenCV的视频播放变慢

分别使用tkinter,pygame,OpenCV播放视频,发现均有视频播放变慢的现象,源码如下:
使用tkinter,OpenCV播放视频:


from tkinter import *
import cv2
from PIL import Image, ImageTk

def video_play():
    while video.isOpened():
        ret, frame = video.read()  # 读取照片
        # print('读取成功')
        if ret == True:
            img = cv2.cvtColor(frame, cv2.COLOR_BGR2RGBA)  # 转换颜色使播放时保持原有色彩
            current_image = Image.fromarray(img).resize((1920,1080))  # 将图像转换成Image对象
            imgtk = ImageTk.PhotoImage(image=current_image)
            movieLabel.imgtk = imgtk
            movieLabel.config(image=imgtk)
            movieLabel.update()  # 每执行以此只显示一张图片,需要更新窗口实现视频播放
        else:
            break

root = Tk()
root.overrideredirect(True)
root.state("zoomed")
movieLabel = Label(root,width=1920,height=1080)  # 创建一个用于播放视频的label容器
movieLabel.pack()
while True:
    video = cv2.VideoCapture(r"E:\放松\xjj\掠影\原神\1612179174bfee75ebffaca79a.mp4_last.mp4")  # 使用opencv打开本地视频文件
    video_play()  # 调用video_play实现视频播放

mainloop()

使用pygame,OpenCV播放视频:


import pygame
import sys
import cv2
import numpy as np
import os
import moviepy.editor as mpy


if __name__ == '__main__':
    # 截取背景音乐
    # audio_background = mpy.AudioFileClip('cs1.mp4')
    #
    # audio_background.write_audiofile('cs1.mp3')
    pygame.init()  # 初始化pygame
    FPS = 100
    #设置窗口位置
    os.environ['SDL_VIDEO_WINDOW_POS']="%d,%d" % (5,30)
    FPSClock = pygame.time.Clock()
    size = width, height = 960, 540  # 设置窗口大小
    screen = pygame.display.set_mode(size)  # 显示窗口
    color = (255, 255, 255)  # 设置颜色
    ogg=pygame.mixer.Sound("cs1.mp3")
    #pygame.mixer.music.load("")

    videoCapture = cv2.VideoCapture("cs2.mp4")
    ogg.play()

    while True:
        a=pygame.time.get_ticks()

        if videoCapture.isOpened():
            #从opncv读一段视频进来
            ret, frame = videoCapture.read()
            if ret :
                frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
                # frame = np.asarray(frame.resize((1920, 1080)))
                frame = cv2.resize(frame,(960,540),interpolation=cv2.INTER_CUBIC)
                frame = np.rot90(frame, k=-1)
                frame = pygame.surfarray.make_surface(frame)

                frame=pygame.transform.flip(frame,False,True)

                screen.blit(frame, (0,0))

        for event in pygame.event.get():  # 遍历所有事件
            if event.type == pygame.QUIT:  # 如果单击关闭窗口,则退出
                sys.exit()
        pygame.display.flip()  # 更新全部显示
        FPSClock.tick(FPS)
        pygame.time.get_ticks()

使用OpenCV播放视频:

import cv2
import numpy as np
# import moviepy.editor as mpy
import pygame
pygame.init()
# ogg=pygame.mixer.Sound("cs1.mp3")
# 背景音乐
cap = cv2.VideoCapture("cs1.mp4")
fps = cap.get(cv2.CAP_PROP_FPS)
# ogg.play()
while (True):
    # 读帧
    ret, frame = cap.read()
    # 显示图像
    cv2.imshow("video", cv2.resize(frame,(960,540),interpolation=cv2.INTER_CUBIC))
    # 图像的按比例压缩,
    if cv2.waitKey(int(1000/fps)) & 0xFF == ord('q'):
        break
cap.release()
cv2.destroyAllWindows()

展开全部

  • 写回答

2条回答 默认 最新

  • Ko-walski 2022-10-03 14:18
    关注

    tkinter的我改了下 感觉快了一点
    但是有个问题是 你的播放就没在tkinter里面 不能关闭
    所以我觉得有问题
    其次单纯用opencv还是很快的

    
    from tkinter import *
    import cv2
    from PIL import Image, ImageTk
    
    
    def video_play():
        while True:
            if video.isOpened():
                ret, frame = video.read()  # 读取照片
    
            if ret:
                img = cv2.cvtColor(frame, cv2.COLOR_BGR2RGBA)  # 转换颜色使播放时保持原有色彩
                current_image = Image.fromarray(img).resize((1280, 768))  # 将图像转换成Image对象
    
                imgtk = ImageTk.PhotoImage(image=current_image)
                movieLabel.imgtk = imgtk
                movieLabel.config(image=imgtk)
                movieLabel.update()  # 每执行以此只显示一张图片,需要更新窗口实现视频播放
    
            else:
                break
    
    
    root = Tk()
    root.overrideredirect(True)
    root.state("zoomed")
    movieLabel = Label(root, width=1280, height=768)  # 创建一个用于播放视频的label容器
    movieLabel.pack()
    video = cv2.VideoCapture(r"请君01.mp4")  # 使用opencv打开本地视频文件
    # video.set(cv2.CAP_PROP_FPS, 30)
    # video.set(cv2.CAP_PROP_FRAME_WIDTH, 600)
    # video.set(cv2.CAP_PROP_FRAME_HEIGHT, 320)
    video_play()  # 调用video_play实现视频播放
    
    mainloop()
    
    

    opencv

    import cv2
    vid_cam = cv2.VideoCapture('请君01.mp4')
    vid_cam.set(cv2.CAP_PROP_FPS, 25)
    vid_cam.set(cv2.CAP_PROP_FRAME_WIDTH, 640)
    vid_cam.set(cv2.CAP_PROP_FRAME_HEIGHT, 360)
    
    while vid_cam.isOpened():
        ret, image_frame = vid_cam.read()
        cv2.imshow('frame', cv2.resize(image_frame,(960,540),interpolation=cv2.INTER_CUBIC))
        FPS_MS = int((1/30)*1000)
        if cv2.waitKey(FPS_MS) & 0xFF == ord('q'):
            break
    vid_cam.release()
    cv2.destroyAllWindows()
    
    

    展开全部

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
    开向幼儿园的车 2022-10-03 22:54

    还是比较慢的,不知道能不能看得出来,一个是原始视频,一个是使用OpenCV播放的

    img

    img

    回复
    Ko-walski 回复 开向幼儿园的车 2022-10-04 00:42

    有区别吗 我看不出来试试多线程

    
    from threading import Thread
    import cv2, time
    
    
    class ThreadedCamera(object):
        def __init__(self, src=0):
            self.capture = cv2.VideoCapture(src)
            self.capture.set(cv2.CAP_PROP_BUFFERSIZE, 2)
    
            # FPS = 1/X
            # X = desired FPS
            self.FPS = 1 / 30
            self.FPS_MS = int(self.FPS * 1000)
    
            # Start frame retrieval thread
            self.thread = Thread(target=self.update, args=())
            self.thread.daemon = True
            self.thread.start()
    
        def update(self):
            while True:
                if self.capture.isOpened():
                    (self.status, self.frame) = self.capture.read()
                time.sleep(self.FPS)
    
        def show_frame(self):
            cv2.imshow('frame', self.frame)
            cv2.waitKey(self.FPS_MS)
    
    
    if __name__ == '__main__':
        src = '请君01.mp4'
        threaded_camera = ThreadedCamera(src)
        while True:
            try:
                threaded_camera.show_frame()
            except AttributeError:
                pass
    
    

    回复
    开向幼儿园的车 回复 Ko-walski 2022-10-04 02:14

    有没有一种可能,是我的电脑的问题……

    回复
    展开全部4条评论
查看更多回答(1条)
编辑
预览

报告相同问题?

问题事件

  • 系统已结题 10月11日
  • 已采纳回答 10月4日
  • 创建了问题 10月3日

悬赏问题

  • ¥15 PADS Logic 原理图
  • ¥15 PADS Logic 图标
  • ¥15 电脑和power bi环境都是英文如何将日期层次结构转换成英文
  • ¥20 气象站点数据求取中~
  • ¥15 如何获取APP内弹出的网址链接
  • ¥15 wifi 图标不见了 不知道怎么办 上不了网 变成小地球了
手机看
程序员都在用的中文IT技术交流社区

程序员都在用的中文IT技术交流社区

专业的中文 IT 技术社区,与千万技术人共成长

专业的中文 IT 技术社区,与千万技术人共成长

关注【CSDN】视频号,行业资讯、技术分享精彩不断,直播好礼送不停!

关注【CSDN】视频号,行业资讯、技术分享精彩不断,直播好礼送不停!

客服 返回
顶部