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

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

相关文章

Vue3视频播放组件 vue3-video-play使用方式

《Vue3视频播放组件vue3-video-play使用方式》vue3-video-play是Vue3的视频播放组件,基于原生video标签开发,支持MP4和HLS流,提供全局/局部引入方式,可监听... 目录一、安装二、全局引入三、局部引入四、基本使用五、事件监听六、播放 HLS 流七、更多功能总结在 v

uni-app小程序项目中实现前端图片压缩实现方式(附详细代码)

《uni-app小程序项目中实现前端图片压缩实现方式(附详细代码)》在uni-app开发中,文件上传和图片处理是很常见的需求,但也经常会遇到各种问题,下面:本文主要介绍uni-app小程序项目中实... 目录方式一:使用<canvas>实现图片压缩(推荐,兼容性好)示例代码(小程序平台):方式二:使用uni

Python进行word模板内容替换的实现示例

《Python进行word模板内容替换的实现示例》本文介绍了使用Python自动化处理Word模板文档的常用方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友... 目录技术背景与需求场景核心工具库介绍1.获取你的word模板内容2.正常文本内容的替换3.表格内容的

Git进行版本控制的实战指南

《Git进行版本控制的实战指南》Git是一种分布式版本控制系统,广泛应用于软件开发中,它可以记录和管理项目的历史修改,并支持多人协作开发,通过Git,开发者可以轻松地跟踪代码变更、合并分支、回退版本等... 目录一、Git核心概念解析二、环境搭建与配置1. 安装Git(Windows示例)2. 基础配置(必

Android实现图片浏览功能的示例详解(附带源码)

《Android实现图片浏览功能的示例详解(附带源码)》在许多应用中,都需要展示图片并支持用户进行浏览,本文主要为大家介绍了如何通过Android实现图片浏览功能,感兴趣的小伙伴可以跟随小编一起学习一... 目录一、项目背景详细介绍二、项目需求详细介绍三、相关技术详细介绍四、实现思路详细介绍五、完整实现代码

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指令