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

2023-10-08 04:44

本文主要是介绍基于图片相似度对视频进行抽帧,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

文章目录

  • 需求
  • 方法
  • 代码

需求

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

方法

基于图片相似度来选取不同的图片进行保存,相似度计算方法主要参考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变成一维listimg_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 到8x8image = 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 + 1return 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=Noneframe_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)continueelse:# 计算图像之间的相似度current_image = cv2.resize(image,(128,128))#ssim#similarity = compare_ssim(current_image, previous_image,channel_axis=2)#差异hashhash1 = 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_imageframe_count += 1print(".",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)

这篇关于基于图片相似度对视频进行抽帧的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/162770

相关文章

Java实现将HTML文件与字符串转换为图片

《Java实现将HTML文件与字符串转换为图片》在Java开发中,我们经常会遇到将HTML内容转换为图片的需求,本文小编就来和大家详细讲讲如何使用FreeSpire.DocforJava库来实现这一功... 目录前言核心实现:html 转图片完整代码场景 1:转换本地 HTML 文件为图片场景 2:转换 H

Java实现在Word文档中添加文本水印和图片水印的操作指南

《Java实现在Word文档中添加文本水印和图片水印的操作指南》在当今数字时代,文档的自动化处理与安全防护变得尤为重要,无论是为了保护版权、推广品牌,还是为了在文档中加入特定的标识,为Word文档添加... 目录引言Spire.Doc for Java:高效Word文档处理的利器代码实战:使用Java为Wo

基于C#实现PDF转图片的详细教程

《基于C#实现PDF转图片的详细教程》在数字化办公场景中,PDF文件的可视化处理需求日益增长,本文将围绕Spire.PDFfor.NET这一工具,详解如何通过C#将PDF转换为JPG、PNG等主流图片... 目录引言一、组件部署二、快速入门:PDF 转图片的核心 C# 代码三、分辨率设置 - 清晰度的决定因

Python从Word文档中提取图片并生成PPT的操作代码

《Python从Word文档中提取图片并生成PPT的操作代码》在日常办公场景中,我们经常需要从Word文档中提取图片,并将这些图片整理到PowerPoint幻灯片中,手动完成这一任务既耗时又容易出错,... 目录引言背景与需求解决方案概述代码解析代码核心逻辑说明总结引言在日常办公场景中,我们经常需要从 W

Nginx中配置使用非默认80端口进行服务的完整指南

《Nginx中配置使用非默认80端口进行服务的完整指南》在实际生产环境中,我们经常需要将Nginx配置在其他端口上运行,本文将详细介绍如何在Nginx中配置使用非默认端口进行服务,希望对大家有所帮助... 目录一、为什么需要使用非默认端口二、配置Nginx使用非默认端口的基本方法2.1 修改listen指令

使用Python实现无损放大图片功能

《使用Python实现无损放大图片功能》本文介绍了如何使用Python的Pillow库进行无损图片放大,区分了JPEG和PNG格式在放大过程中的特点,并给出了示例代码,JPEG格式可能受压缩影响,需先... 目录一、什么是无损放大?二、实现方法步骤1:读取图片步骤2:无损放大图片步骤3:保存图片三、示php

Python文本相似度计算的方法大全

《Python文本相似度计算的方法大全》文本相似度是指两个文本在内容、结构或语义上的相近程度,通常用0到1之间的数值表示,0表示完全不同,1表示完全相同,本文将深入解析多种文本相似度计算方法,帮助您选... 目录前言什么是文本相似度?1. Levenshtein 距离(编辑距离)核心公式实现示例2. Jac

MySQL按时间维度对亿级数据表进行平滑分表

《MySQL按时间维度对亿级数据表进行平滑分表》本文将以一个真实的4亿数据表分表案例为基础,详细介绍如何在不影响线上业务的情况下,完成按时间维度分表的完整过程,感兴趣的小伙伴可以了解一下... 目录引言一、为什么我们需要分表1.1 单表数据量过大的问题1.2 分表方案选型二、分表前的准备工作2.1 数据评估

MySQL进行分片合并的实现步骤

《MySQL进行分片合并的实现步骤》分片合并是指在分布式数据库系统中,将不同分片上的查询结果进行整合,以获得完整的查询结果,下面就来具体介绍一下,感兴趣的可以了解一下... 目录环境准备项目依赖数据源配置分片上下文分片查询和合并代码实现1. 查询单条记录2. 跨分片查询和合并测试结论分片合并(Shardin

SpringBoot结合Knife4j进行API分组授权管理配置详解

《SpringBoot结合Knife4j进行API分组授权管理配置详解》在现代的微服务架构中,API文档和授权管理是不可或缺的一部分,本文将介绍如何在SpringBoot应用中集成Knife4j,并进... 目录环境准备配置 Swagger配置 Swagger OpenAPI自定义 Swagger UI 底