如何使用python自动化对比视频图片是否相同

背景
谁掌握了视频,谁就掌握了流量,谁掌握了流量,谁就掌握了金钱。在我们IT行业的很多部门都有涉及到视频,包括视频的制作,图片转视频,视频转图片等等。而我就有一部分工作就是测试合成视频这款工具的功能,其中有50多款视频合成模板,版本测试期间这款工具都是正常的,但是难免之后会出故障,所以平时也需要进行回归测试,如果手动进行回归,将是一个很大的工作量,所以自动化回归视频测试判断就孕育而生了。

简介
主思想是:从视频中抽取部分帧进行对比,如果每一帧都一样,那么我们就可以认为这两个视频是一样的。在我的业务中就是合成的视频和标准的视频一样,那么就是我们的工具没有问题。

核心技术
视频抽帧
图片对比(有两种方式)

一、视频抽帧 

下面的为每隔200帧则写一帧到我们的本地文件中,当所有视频帧都读取完成后success则变成False,然后读帧结束,帧的图片名为四位数,如:1000.jpg、1001.jpg,1002.jpg

'''视频抽帧'''       
 cap = cv2.VideoCapture('c:/1/1.mp4')
        # 第几帧
        frame_count = 1
        # 隔着多少帧取一张
        frame_rate = 200
        success = True
        # 计数
        num = 0
        while (success):
            #cap.read()进行读,cv2.imwrite()进行写,当读结束时,success变成False
            success, frame = cap.read()
            if success == True:
                if frame_count % frame_rate == 0:
                    cv2.imwrite('c:/2/' + "%03d.jpg" % num, frame)
                    num += 1
            frame_count = frame_count + 1

二、图片对比 

方式一、使用math.sqrt就可对比两张图片,返回值是0.0则是图片一样,否则就是图片不一样
方式二、使用np.any(cv2.subtract(image1,imge2))就可对比两张图片,返回值是True则图片一样、
返回False就表示图片不一样

    '''图片对比'''
    #方式一
    #使用对比两张图片的差值判断图片是否相同,值为0则相同,值越大则差异越大
    image1 = Image.open(c:\2\1.jpg)
    image2 = Image.open(c:\2\2.jpg)
    histogram1 = image1.histogram()
    histogram2 = image2.histogram()

    differ = math.sqrt(reduce(operator.add, list(map(lambda a,b: (a-b)**2,histogram1, histogram2)))/len(histogram1))
    if differ>0 or differ<0:
        print('两张图片不一样')
    if differ==0:
        print('两张图片一样')

    #方式二
    #判断两张图片是否有差异,有差异则把差异的部分合成一张图片,用于观察差异的部分
    image1 = cv2.imread(c:\2\1.jpg)
    image2 = cv2.imread(c:\2\1.jpg)
    difference = cv2.subtract(image1, image2)
    result = not np.any(difference)  # if difference is all zeros it will return False

    if result is True:
        print('图片一样')
    else:
        cv2.imwrite("c:\difference\result.jpg", difference)
        return False

三、具体代码

以下是我自己封装的代码,适合于自动对比和识别dect文件夹里和source文件夹里的视频的一致性,(注:dect文件夹里的视频和source文件夹的视频名字格式需要一样)

# coding=utf-8
import os
import shutil
import cv2
import cv2
import numpy as np
from PIL import Image
import math
import operator
from functools import reduce
'''此方法用于视频切割为图片,入参为切割的视频地址和输出的图片地址'''
def videoImage(dir_vieo,dir_image):
    # mp4存放的路径
    videos_src_path = dir_vieo
    # 保存的路径,会在路径下创建mp4文件名的文件夹保存图片
    videos_save_path = dir_image
    #获取目标文件夹得视频列表,方便下面遍历
    videos = os.listdir(videos_src_path)

    for each_video in videos:
        print('Video Name :', each_video)
        # get the name of each video, and make the directory to save frames
        each_video_name, _ = each_video.split('.')
        url = videos_save_path + '/' + each_video_name
        if os.path.exists(url):
            # image的文件夹作为临时存储容器,清空用于保持文件夹得简洁性
            shutil.rmtree(url)
        os.mkdir(url)
        each_video_save_full_path = os.path.join(videos_save_path, each_video_name) + '/'
        # get the full path of each video, which will open the video tp extract frames
        each_video_full_path = os.path.join(videos_src_path, each_video)
        #cv2.VideoCapture()是用于从视频文件、图片序列、摄像头捕获视频并返回为cap对象
        cap = cv2.VideoCapture(each_video_full_path)
        # 第几帧
        frame_count = 1
        # 隔着多少帧取一张
        frame_rate = 200
        success = True
        # 计数
        num = 0
        while (success):
            #cap.read()进行读,cv2.imwrite()进行写,当读结束时,success变成False
            success, frame = cap.read()
            if success == True:
                if frame_count % frame_rate == 0:
                    cv2.imwrite(each_video_save_full_path + each_video_name + "%03d.jpg" % num, frame)
                    num += 1
            frame_count = frame_count + 1
        print('image numbers:', num)

'''使用对比两张图片的差值判断图片是否相同,值为0则相同,值越大则差异越大'''
def compare(pic1,pic2):
    '''
    :param pic1: 图片1路径
    :param pic2: 图片2路径
    :return: 返回对比的结果
    '''
    if os.path.exists(pic1):
        pass
    else:
        raise IOError(f'图片不存在,请您仔细观察路径是否填写错误{pic1}')
    if os.path.exists(pic2):
        pass
    else:
        raise IOError(f'图片不存在,请您仔细观察路径是否填写错误{pic2}')
    image1 = Image.open(pic1)
    image2 = Image.open(pic2)
    histogram1 = image1.histogram()
    histogram2 = image2.histogram()

    differ = math.sqrt(reduce(operator.add, list(map(lambda a,b: (a-b)**2,histogram1, histogram2)))/len(histogram1))
    if differ>0 or differ<0:
        return False
    if differ==0:
        return True
'''判断两张图片是否有差异,有差异则把差异的部分合成一张图片,用于观察差异的部分'''
def equalImage(file1,file2):
    if os.path.exists(file1):
        pass
    else:
        raise IOError(f'图片不存在,请您仔细观察路径是否填写错误{file1}')
    if os.path.exists(file2):
        pass
    else:
        raise IOError(f'图片不存在,请您仔细观察路径是否填写错误{file2}')
    image1 = cv2.imread(file1)
    image2 = cv2.imread(file2)
    difference = cv2.subtract(image1, image2)
    result = not np.any(difference)  # if difference is all zeros it will return False

    if result is True:
        return True
    else:
        cv2.imwrite("./difference/result.jpg", difference)
        return False

下面是总方法,用于调用上面的方法 

'''此方法用于对比两个视频是否相同,为了清晰地说明技术,所以两个对比的视频名字需要一样'''
def equalsVideoVideo():
    dir_vs = './video/source'
    dir_is = './image/source'
    dir_vd = './video/dect'
    dir_id = './image/dect'
    #使用自定义的方法对视频进行切割成多个图片
    videoImage(dir_vs,dir_is)
    videoImage(dir_vd,dir_id)
    #遍历视频,对每个视频产生的图片进行对比
    for video in  os.listdir(dir_vs):
        video_name,_ = video.split('.')
        source_list = os.listdir(f'{dir_is}/{video_name}')
        dect_list = os.listdir(f'{dir_id}/{video_name}')
        result = True
        for file1,file2 in zip(source_list,dect_list):
            result = compare(dir_is+'/'+video_name+'/'+file1,dir_id+'/'+video_name+'/'+file2)
            if result == False:
                result = False
        if result:
            print(f'两个视频:{video_name}.mp4一样')
        else:
            print(f'两个视频:{video_name}.mp4不一样')

if __name__ == '__main__':
    equalsVideoVideo()

测试人员使用python批量对比两个视频是否一致篇结束,欢迎到我的主页观看其他技术类博客~

  • 1
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值