基于图片相似度对视频进行抽帧

文章目录

需求

做深度学习需要自己收集图片,其中一种是收集视频,然后将视频转换成图片。在视频转图片过程中,会存在大量的高度相似帧,对于模型训练无用,而且增加标注成本,如何选取有足够差异的图片是我们需要的。

方法

基于图片相似度来选取不同的图片进行保存,相似度计算方法主要参考https://aistudio.baidu.com/projectdetail/4185629?channelType=0&channel=0 这篇中的方法。

代码

直接上代码,内容简单,很容易看明白。代码中提供基于hash的三种方法和一种结构相似性方法,需要手动改代码来切换方法及相关阈值。

import os
import cv2
import numpy as np
import sys
import shutil
from datetime import datetime
from skimage.metrics import structural_similarity as compare_ssim

# 均值哈希算法
def ahash(image):
    # 将图片缩放为8*8的
    image = cv2.resize(image, (8, 8), interpolation=cv2.INTER_CUBIC)
    # 将图片转化为灰度图
    gray = cv2.cvtColor(image, cv2.COLOR_RGB2GRAY)
    # s为像素和初始灰度值,hash_str为哈希值初始值
    s = 0
    # 遍历像素累加和
    for i in range(8):
        for j in range(8):
            s = s + gray[i, j]
    # 计算像素平均值
    avg = s / 64
    # 灰度大于平均值为1相反为0,得到图片的平均哈希值,此时得到的hash值为64位的01字符串
    ahash_str = ''
    for i in range(8):
        for j in range(8):
            if gray[i, j] > avg:
                ahash_str = ahash_str + '1'
            else:
                ahash_str = ahash_str + '0'
    result = ''
    for i in range(0, 64, 4):
        result += ''.join('%x' % int(ahash_str[i: i + 4], 2))
    # print("ahash值:",result)
    return result
# phash
def phash(img):
    # 加载并调整图片为32*32的灰度图片
    img1 = cv2.resize(img, (32, 32),cv2.COLOR_RGB2GRAY)# 创建二维列表
    h, w = img.shape[:2]
    vis0 = np.zeros((h, w), np.float32)
    vis0[:h, :w] = img1
​
    # DCT二维变换
    # 离散余弦变换,得到dct系数矩阵
    img_dct = cv2.dct(cv2.dct(vis0))
    img_dct.resize(8,8)
    # 把list变成一维list
    img_list = np.array().flatten(img_dct.tolist())
    # 计算均值
    img_mean = cv2.mean(img_list)
    avg_list = ['0' if i<img_mean else '1' for i in img_list]
    return ''.join(['%x' % int(''.join(avg_list[x:x+4]),2) for x in range(0,64,4)])
#差异值哈希算法
def dhash(image):
    #将图片resize 到8x8
    image = cv2.resize(image,(9,8),interpolation=cv2.INTER_CUBIC)
    #转成灰度图
    gray = cv2.cvtColor(image,cv2.COLOR_RGB2GRAY)
    #计算dhash 二进制
    dhash_str =""
    for i in range(8):
        for j in range(8):
            if gray[i,j]>gray[i,j+1]:
                dhash_str = dhash_str+"1"
            else:
                dhash_str = dhash_str+"0"
    #二进制转十六近制
    result = ""
    for i in range(0,64,4):
        result += "".join("%x" %int(dhash_str[i:i+4],2))
    return result
# 计算两个哈希值之间的差异
def campHash(hash1, hash2):
    n = 0
    # hash长度不同返回-1,此时不能比较
    if len(hash1) != len(hash2):
        return -1
    # 如果hash长度相同遍历长度
    for i in range(len(hash1)):
        if hash1[i] != hash2[i]:
            n = n + 1
    return n
def extract_frames(video_path, similarity_threshold, output_dir):
    # 读取视频文件
    cap = cv2.VideoCapture(video_path)

    # 创建输出文件夹
    if os.path.exists(output_dir):
        shutil.rmtree(output_dir)
    os.makedirs(output_dir)
    #要保存的图片
    previous_image=None
    frame_count=0
    # 遍历视频帧
    while True:
        # 读取一帧
        ret, frame = cap.read()

        # 如果读取到最后一帧,退出循环
        if not ret:
            break

        # 将帧转换为图像
        image = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
        
        if previous_image is None:
            previous_image=cv2.resize(image,(128,128))
            # 获取当前时间  
            now = datetime.now()            
            # 格式化成指定的时间格式  
            formatted_time = now.strftime("%Y_%m_%d-%H_%M_%S")
            # 保存帧
            cv2.imwrite(os.path.join(output_dir,f"{formatted_time}_{frame_count}.jpg"),frame)
            continue
        else:
            # 计算图像之间的相似度
            current_image = cv2.resize(image,(128,128))
            #ssim
            #similarity = compare_ssim(current_image, previous_image,channel_axis=2)
            #差异hash
            hash1 = ahash(previous_image)
            hash2 = ahash(current_image)
            similarity = campHash(hash1,hash2)

            # ssim如果相似度小于阈值,则不够相似,则抽取帧
            #if similarity < similarity_threshold:
            # dhash如果相似度大于阈值,则不够相似,则抽取帧
            if similarity > similarity_threshold:
                # 获取当前时间  
                now = datetime.now()            
                # 格式化成指定的时间格式  
                formatted_time = now.strftime("%Y_%m_%d-%H_%M_%S")
                # 保存帧
                cv2.imwrite(os.path.join(output_dir,f"{formatted_time}_{frame_count}.jpg"),frame)

                # 更新上一帧
                previous_image = current_image
        frame_count += 1
        print(".",end="")
        sys.stdout.flush()

    cap.release()

if __name__ == "__main__":
    # 视频路径
    video_path = "../jiabo/20230829/跳远30fps_20230829194849_CH01.avi"

    # ssim相似度阈值
    #similarity_threshold = 0.9
    # dhash 相似度阈值
    similarity_threshold = 10

    # 输出文件夹
    output_dir = "split_output_ahash"

    # 抽取帧
    extract_frames(video_path, similarity_threshold, output_dir)
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
智慧校园整体解决方案是响应国家教育信息化政策,结合教育改革和技术创新的产物。该方案以物联网、大数据、人工智能和移动互联技术为基础,旨在打造一个安全、高效、互动且环保的教育环境。方案强调从数字化校园向智慧校园的转变,通过自动数据采集、智能分析和按需服务,实现校园业务的智能化管理。 方案的总体设计原则包括应用至上、分层设计和互联互通,确保系统能够满足不同用户角色的需求,并实现数据和资源的整合与共享。框架设计涵盖了校园安全、管理、教学、环境等多个方面,构建了一个全面的校园应用生态系统。这包括智慧安全系统、校园身份识别、智能排课及选课系统、智慧学习系统、精品录播教室方案等,以支持个性化学习和教学评估。 建设内容突出了智慧安全和智慧管理的重要性。智慧安全管理通过分布式录播系统和紧急预案一键启动功能,增强校园安全预警和事件响应能力。智慧管理系统则利用物联网技术,实现人员和设备的智能管理,提高校园运营效率。 智慧教学部分,方案提供了智慧学习系统和精品录播教室方案,支持专业级学习硬件和智能化网络管理,促进个性化学习和教学资源的高效利用。同时,教学质量评估中心和资源应用平台的建设,旨在提升教学评估的科学性和教育资源的共享性。 智慧环境建设则侧重于基于物联网的设备管理,通过智慧教室管理系统实现教室环境的智能控制和能效管理,打造绿色、节能的校园环境。电子班牌和校园信息发布系统的建设,将作为智慧校园的核心和入口,提供教务、一卡通、图书馆等系统的集成信息。 总体而言,智慧校园整体解决方案通过集成先进技术,不仅提升了校园的信息化水平,而且优化了教学和管理流程,为学生、教师和家长提供了更加便捷、个性化的教育体验。
经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。 经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。 经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。 经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值