Video to picture (save a picture every few frames) opencv implementation

If you want to automatically capture a picture of a video, but don't want to manually pause the capture, you can try to use opencv to automatically capture it (for example, if you want to automatically capture classic lines and pictures of your favorite movies).

Background description : A small accident, the screen recording video has no sound, I want to capture the PPT in the video, the 1-hour video, it is too slow to capture one by one, I have a chance to try it with opencv.

Question 1 : At the beginning, the code intercepted each frame, and found that there are a total of 42798 frames, which is too many, and the intercepted pictures have many repetitions.

Solution : Intercept and save every frame, how many intervals, the default is 80 for the time being, the effect is good (you can change it according to your own video and effect). (code show as below)

Question 2 : Can you make the code itself judge and save according to the difference between the pictures? leaving only the changed pictures,

Solution : See the second procedure for solution. The core code of the program skimage.measure.compare_ssim (X, Y, ...) calculates the average structural similarity index between two images, please refer to my other blog https://mp.csdn.net/console /editor/html/109428505

Notice:

  • If you want to try the code, configure opencv, pip install -i https://mirrors.aliyun.com/pypi/simple opencv-python==4.1.0.25
    For details, see: https://blog.csdn.net/dujuancao11/article/ details/107468687
  • cap = cv2.VideoCapture('2.mp4') 2.mp4 to your video name
  • The following code only tries MP4 type files, and I haven't tried anything else for the time being. It needs to be updated and improved.
# 视频分解图片
# 1 load 2 info 3 parse 4 imshow imwrite
import cv2
import os
# 获取一个视频打开cap 参数1 file name
#cap = cv2.VideoCapture("1.mp4")
#cv2.VideoCapture(0, cv2.CAP_DSHOW) # 摄像头截取
cap = cv2.VideoCapture('2.mp4')
isOpened = cap.isOpened # 判断是否打开‘
print(isOpened)
# 获取信息 宽高
n_frame = int(cap.get(cv2.CAP_PROP_FRAME_COUNT))
print('总帧数:',n_frame) # 整个视频的总帧数
fps = cap.get(cv2.CAP_PROP_FPS) # 帧率 每秒展示多少张图片
width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH)) # w
height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT)) # h
print('帧数、宽度、高度分别为:',fps,width,height) # 帧率 宽 高
i = 0 # 记录读取多少帧
frameFrequency = 80 # 每frameFrequency保存一张图片
while(isOpened):
    # 结束标志是否读取到最后一帧
    if i == n_frame:
        break
    else:
        i = i+1
    (flag,frame) = cap.read() # read方法 读取每一张 flag是否读取成功 frame 读取内容
    fileName = 'image'+str(i)+'.jpg' # 名字累加
    # True表示读取成功 进行·写入
    # if 判断需要有冒号
    #if flag == True:
    outPutDirName = './d/' # 设置保存路径
    if not os.path.exists(outPutDirName):
        # 如果文件目录不存在则创建目录
        os.makedirs(outPutDirName)
    if i % frameFrequency == 0:
        print(fileName)
        cv2.imwrite(outPutDirName+fileName,frame,[cv2.IMWRITE_JPEG_QUALITY,100])# 质量控制 100最高
print('end!')

code running result 

import os
import cv2
from skimage.measure import compare_ssim
'''相邻两个文件比较相似度,相似就把第二个加到新列表(删除列表)里,然后进行新列表去重,统一删除。
  例如:有文件1-10,首先1和2相比较,若相似,则把2加入到新列表里,再接着2和3相比较,若不相似,则继续进行3和4比较...一直比到最后,然后删除新列表里的图片
   只对于连续图片(例一个视频里截下的图片)准确率也较高,其效率高'''
def delete(filename1):
    os.remove(filename1)
if __name__ == '__main__':
    path = r'./E/' # 文件所在路径
    img_path = path
    imgs_n = [] # 新建的删除列表
    i = 0 # 用来统计删了第几张图片
    img_files = [os.path.join(rootdir, file) for rootdir, _, files in os.walk(path) for file in files if
                 (file.endswith('.jpg'))]
    for currIndex, filename in enumerate(img_files):
        if not os.path.exists(img_files[currIndex]):
            print('not exist', img_files[currIndex])
            break
        img = cv2.imread(img_files[currIndex])
        img1 = cv2.imread(img_files[currIndex + 1])
        # https://cloud.tencent.com/developer/section/1414961 开发者手册链接
        # 本程序最核心的代码
        # skimage.measure.compare_ssim(X,Y,...)
        # 计算两幅图像之间的平均结构相似性指数
        ssim = compare_ssim(img, img1, multichannel=True)
        # 相似度大于0.9就加入删除列表
        if ssim > 0.9:
            imgs_n.append(img_files[currIndex + 1]) # 加入新建删除列表
            i = i+1 # 每加入一个就会删除
            print(img_files[currIndex], img_files[currIndex + 1], ssim)
            print('删除次数', i)
        # 否则不删除,给出两图片的相似度
        else:
            print('small_ssim',img_files[currIndex], img_files[currIndex + 1], ssim)
        currIndex += 1
        if currIndex >= len(img_files)-1:
            break
    for image in imgs_n:
        delete(image)
  • operation result

 A total of 294 pictures can be found deleted

Folder situation before processing (403 in total):

 

 

After processing the folder situation (109 remaining), click to open the check and find that similar pictures are basically deleted, to achieve the goal:

Guess you like

Origin blog.csdn.net/dujuancao11/article/details/109404108#comments_20891748