使用python-opencv模块cv2.VideoCapture按时间截取图片或者视频帧数并存储

opencv-python将文件夹中的视频截取为图片并存储

读取一个文件夹下的所有文件,对于视频文件每0.5秒进行截取并存储到新的文件中

import cv2,os
save_path=r"D:"      #存储的位置
path = r"D:\CowRestAPI\test"    #要截取视频的文件夹

filelist = os.listdir(path)     #读取文件夹下的所有文件
print(filelist)     
for item in filelist:  
    if item.endswith('.mp4'):     #根据自己的视频文件后缀来写,我的视频文件是mp4格式
        print(item)
        try:
            src = os.path.join(path, item)
            vid_cap = cv2.VideoCapture(src)    #传入视频的路径
            success, image = vid_cap.read()
            count = 0
            while success:
                vid_cap.set(cv2.CAP_PROP_POS_MSEC, 0.5 * 1000 * count)   #截取图片的方法  此处是0.5秒截取一个  可以改变参数设置截取间隔的时间
                video_to_picture_path= os.path.join(save_path, item.split(".")[0])    #视频文件夹的命名
                if not os.path.exists(video_to_picture_path):   #创建每一个视频存储图片对应的文件夹
                    os.makedirs(video_to_picture_path)
                cv2.imwrite(video_to_picture_path+"/" + str(count) + ".jpg",      
                            image)       #存储图片的地址 以及对图片的命名
                success, image = vid_cap.read()
                count += 1
            print('Total frames: ', count)     #打印截取的图片数目 
        except:
            print("error")

success, image = vid_cap.read()函数输出的是两个参数,第一个参数success 为True 或者False,代表有没有读取到图片第二个参数 image 表示截取到一帧的图片。

以上代码在截取某些时长特殊视频会出现无限截图的结果 也就是success, image = vid_cap.read()函数输出success一直是True 所以对代码进行了修改来避免这个错误

参考 OpenCV VideoCapture.get()参数详解

https://blog.csdn.net/u011436429/article/details/80604590

函数以及他的作用:

cv2.VideoCapture.get(0) 	视频文件的当前位置(播放)以毫秒为单位
cv2.VideoCapture.get(1) 	基于以0开始的被捕获或解码的帧索引
cv2.VideoCapture.get(2) 	视频文件的相对位置(播放):0=电影开始,1=影片的结尾。
cv2.VideoCapture.get(3) 	在视频流的帧的宽度
cv2.VideoCapture.get(4) 	在视频流的帧的高度
cv2.VideoCapture.get(5) 	帧速率
cv2.VideoCapture.get(6) 	编解码的4字-字符代码
cv2.VideoCapture.get(7) 	视频文件中的帧数

这次的修正主要是使用cv2.VideoCapture.get(0) 这个函数来确定每次截图之后视频的当前位置来确定视频是否走到结尾,之前代码会发生错误的原因就是:视频截图到最后的一个位置,会无限重复保存这张图片,所以加一个判断来对特殊的视频结束当前的循环。

以下是修改之后的代码(主要是对while success:这个循环下的代码进行修改其余意思都一样)

import os,cv2
def process_video_to_image(folder_path,  xvalue, yvalue, width, height):
    try:
        #通过视频位置读取视频
        vid_cap = cv2.VideoCapture(os.path.join(folder_path,"456.mp4"))
        
        #获取视频的总时长
        # if vid_cap.isOpened():
            #获取视频的帧率
            # rate=vid_cap.get(5)
            #获取视频的帧数
            # FrameNumber=vid_cap.get(7)
            # duration=FrameNumber/rate
            #视频的秒数
            # print(duration)

        success, image = vid_cap.read()
        count = 0
        while success:
            temp = vid_cap.get(0)
            cv2.imwrite(folder_path + str(count) + ".jpg",
                        image[yvalue:yvalue + height, xvalue:xvalue + width])  # save frame as JPEG file
            count += 1
            vid_cap.set(cv2.CAP_PROP_POS_MSEC, 0.5 * 1000 * count)
            success, image = vid_cap.read()
            if temp == vid_cap.get(0):
                print("视频异常,结束循环")
                break
        print('Total frames: ', count)
    except:
        return False
    return True

base_images_path=os.path.join(os.path.dirname(os.path.abspath(__file__)) ,r"test")
folder_path = base_images_path + os.sep   #视频位置
#200这几个参数是对图片的大小进行了设置
process_video_to_image(folder_path,200,200,200,200)

解决无限循环截图的错误

通过视频的帧数来截图

import cv2,os

  #use timeF
save_path=r"D:\CowRestAPI\test"
path = r"D:\CowRestAPI\test"
filelist = os.listdir(path)

for item in filelist:
	if item.endswith('.mp4'):
		print(item)
		video_to_picture_path= os.path.join(save_path, item.split(".")[0])
		try:
			if not os.path.exists(video_to_picture_path):
				os.makedirs(video_to_picture_path)
			src = os.path.join(path, item)

			vc = cv2.VideoCapture(src) #读入视频文件 
			c=1

			if vc.isOpened(): #判断是否正常打开 
				rval , frame = vc.read() 
			else: 
				rval = False

			timeF = 6 #视频帧计数间隔频率
			m = 1
			while rval:  #循环读取视频帧 
				rval, frame = vc.read() 
				# print(frame)
				(h, w) = frame.shape[:2]
				center = (w / 2, h / 2)
				# print(center)
				M = cv2.getRotationMatrix2D(center, -90, 1.0)
				rotated = cv2.warpAffine(frame, M, (w, h))

				if(c%timeF == 0): #每隔timeF帧进行存储操作
					cv2.imwrite(video_to_picture_path + "/" + str(m) + '.jpg', rotated)#存储为图像
					m = m + 1
				c = c + 1
				cv2.waitKey(1)
			vc.release()
		except:
			print("error")

你可能感兴趣的:(python)