目录
基本思路
5.1 将视频打散为图片
5.2比较图像相似度
5.2.1 基于相等比较图像相似度
5.2.2 基于numpy计算图片是否相等
5.2.3 基于哈希(以均值哈希算法为例)
5.3 视频截取:ffmpeg
5.4 综合运用
5.4.1练习一
5.4.2练习二
基本思路
1.将视频打散为图片
2.选择合适的方法(相等、numpy、哈希)比较图像相似度
3.根据相似度,去除重复镜头
5.1 将视频打散为图片其中,vc=cv2.VideoCapture()
参数为0时,即vc=cv2.VideoCapture(0),表示打开笔记本的内置摄像头;
参数为视频文件路径,即vc=cv2.VideoCapture(“../testi.mp4”),为打开视频文件。
代码如下:
import os import cv2 import subprocess os.chdir(r'D:pythonclass')#转到目录下 v_path='ghz.mp4' image_save='./img'#新建一个文件夹用于放生成的图片 cap=cv2.VideoCapture(v_path) frame_count=cap.get(cv2.CAP_PROP_frame_COUNT)#返回帧数 print(frame_count) for i in range(int(frame_count)): _,img=cap.read() img=cv2.cvtColor(img,cv2.cv2.COLOR_BGR2GRAY) #cv2.COLOR_RGBGRAY cv2.COLOR_BGR2GRAY #大写的都是常量 cv2.imwrite('./img/image{}.jpg'.format(i),img)#把i传进{}中
效果如图:
5.2比较图像相似度 5.2.1 基于相等比较图像相似度涉及函数:operator(标准运算符替代函数)
其中,会用到operator.eq(a,b)。
eq(a, b) 与 a == b 相同。
Operator其他功能参考:operator --- 标准运算符替代函数 — Python 3.10.0 文档
代码如下:
import operator from PIL import Image a=Image.open('./img/image0.jpg') b=Image.open('./img/image0.jpg') print(a) out=operator.eq(a,b) print(out)5.2.2 基于numpy计算图片是否相等
涉及函数:NumPy 算术函数;any()函数。
①umpy包含简单的加减乘除: add(),subtract(),multiply() 和 divide()。
np.subtract(a,b)表示两个数组相减。
②any() 函数: iterable 中的任何一项为 true或可迭代对象为空,则 any() 函数返回 True,否则返回 False。
元素除了是 0、空、FALSE 外都算 TRUE。
代码如下:
import operator from PIL import Image import os os.chdir(r'D:pythonclass') a=Image.open('./img/image0.jpg') b=Image.open('./img/image0.jpg') out=operator.eq(a,b) print(out)5.2.3 基于哈希(以均值哈希算法为例)
基本原理:图片包含了不同频率的部分,其中,亮度变化小的是低频成分,反之为高频。低频成品描述的是大范围的信息,高频成片描述的是细节。小图缺乏细节,所以是低频的。
算法基本思路:
1.缩小图片尺寸为8*8
2.转为灰度图
3.计算像素的灰度平均值
4.基于灰度生成hash值
5.将图像分离为RGB三通道,计算每个通道的相似值
6.对比hash值(计算汉明距离,不同位数越少,图片相似度大)
哈希算法参考:哈希算法-图片相似度计算_chenghaoy的博客-CSDN博客_均值哈希算法
代码如下:
import cv2 import numpy as np import matplotlib.pyplot as plt import os #均值哈希算法 def aHash(img): #缩放为8*8 plt.imshow(img) plt.axis('off') plt.show() img=cv2.resize(img,(8,8)) plt.imshow(img) plt.axis('off') plt.show() #转换为灰度图 gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY) s=0 hash_str='' # s为像素和初值为0,hash_str为hash值初值为'' #遍历累加求像素和 for i in range(8): for j in range(8): s=s + gray[i,j] #求平均灰度 avg=s/64 #灰度大于平均值为1 相反为0 生成图片的hash值 for i in range(8): for j in range(8): if gray[i,j]>avg: hash_str=hash_str+'1' else: hash_str=hash_str+'0' return hash_str # 通过得到RGB每个通道的直方图来计算相似度 def classify_hist_with_split(image1,image2,size=(256,256)): #将图像resize后,分离为RGB三个通道,再计算每个通道的相似值 image1 = cv2.resize(image1,size) image2 = cv2.resize(image2,size) plt.imshow(image1) plt.show() plt.axis('off') plt.imshow(image2) plt.show() plt.axis('off') sub_image1=cv2.split(image1) sub_image2=cv2.split(image2) sub_data=0 for im1,im2 in zip(sub_image1,sub_image2): sub_data+=calculate(im1,im2) sub_data=sub_data/3 return sub_data # 计算单通道的直方图的相似值 def calculate(image1,image2): hist1 = cv2.calcHist([image1],[0],None,[256],[0.0,225.0]) hist2 = cv2.calcHist([image2],[0],None,[256],[0.0,225.0]) plt.plot(hist1,color="r") plt.plot(hist2,color="g") plt.show() # 计算直方图的重合度 degree = 0 for i in range(len(hist1)): if hist1[i]!=hist2[i]: degree=degree+(1-abs(hist1[i])-hist2[i])/max(hist1[i],hist2[i]) else: degree = degree + 1#统计相似 degree = degree / len(hist1) return degree # Hash值对比 def cmpHash(hash1,hash2): n=0 print(hash1) print(hash2) # hash长度不同则返回-1代表传参出错 if len(hash1)!=len(hash2):#!=不等于 return -1 #遍历判断 for i in range(len(hash1)): # 不相等则n计数+1,n最终为相似度 if hash1[i]!=hash2[i]: n=n+1 return n img1 = cv2.imread('./img/image0.jpg') img2 = cv2.imread('./img/image1.jpg') hash1 = aHash(img1) hash2 = aHash(img2) n=cmpHash(hash1,hash2) print('均值哈希算法相似度:',n) n=classify_hist_with_split(img1,img2)#看的是image0和image1 print('三直方图算法相似度:',n)
效果如图:
此外,还可以对分镜头进行比对,去除重复的镜头,将筛选后的图片置于一个文件夹中。
代码如下:
import os import cv2 from PIL import Image os.chdir(r'D:pythonclassvideo') print(os.getcwd()) #for f in os.listdir('./shot'): for i in range(549): img1 = cv2.imread('./img/image{}.jpg'.format(i)) img2 = cv2.imread('./img/image{}.jpg'.format(i+1)) hash1 = aHash(img1) hash2 = aHash(img2) n = cmpHash(hash1,hash2) if (n>32):#可通过改变参数,得到不同的镜头数 print('均值哈希算法相似度:',n/64) cv2.imwrite('./shot/image{}.jpg'.format(i+1),img2)
效果如图:
可以看到,文件夹中已生成图片 (参数不同,图片数也不同)
5.3 视频截取:ffmpeg运用ffmpeg截取1min的视频。
在程序框中输入:ffmpeg -i food.mp4 -ss 1 -t 60 -codec copy foodcut.mp4
将截取的视频命名为 原名cut.mp4
效果如图:
5.4 综合运用在5.3基础上,运用5.1和5.2的方法对所截视频进行处理。
5.4.1练习一代码如下:
import cv2 import numpy as np import matplotlib.pyplot as plt import os #均值哈希算法 def aHash(img): #缩放为8*8 plt.imshow(img) plt.axis('off') plt.show() img=cv2.resize(img,(8,8)) plt.imshow(img) plt.axis('off') plt.show() #转换为灰度图 gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY) s=0 hash_str='' # s为像素和初值为0,hash_str为hash值初值为'' #遍历累加求像素和 for i in range(8): for j in range(8): s=s + gray[i,j] #求平均灰度 avg=s/64 #灰度大于平均值为1 相反为0 生成图片的hash值 for i in range(8): for j in range(8): if gray[i,j]>avg: hash_str=hash_str+'1' else: hash_str=hash_str+'0' return hash_str # 通过得到RGB每个通道的直方图来计算相似度 def classify_hist_with_split(image1,image2,size=(256,256)): #将图像resize后,分离为RGB三个通道,再计算每个通道的相似值 image1 = cv2.resize(image1,size) image2 = cv2.resize(image2,size) plt.imshow(image1) plt.show() plt.axis('off') plt.imshow(image2) plt.show() plt.axis('off') sub_image1=cv2.split(image1) sub_image2=cv2.split(image2) sub_data=0 for im1,im2 in zip(sub_image1,sub_image2): sub_data+=calculate(im1,im2) sub_data=sub_data/3 return sub_data # 计算单通道的直方图的相似值 def calculate(image1,image2): hist1 = cv2.calcHist([image1],[0],None,[256],[0.0,225.0]) hist2 = cv2.calcHist([image2],[0],None,[256],[0.0,225.0]) plt.plot(hist1,color="r") plt.plot(hist2,color="g") plt.show() # 计算直方图的重合度 degree = 0 for i in range(len(hist1)): if hist1[i]!=hist2[i]: degree=degree+(1-abs(hist1[i])-hist2[i])/max(hist1[i],hist2[i]) else: degree = degree + 1#统计相似 degree = degree / len(hist1) return degree # Hash值对比 def cmpHash(hash1,hash2): n=0 print(hash1) print(hash2) # hash长度不同则返回-1代表传参出错 if len(hash1)!=len(hash2):#!=不等于 return -1 #遍历判断 for i in range(len(hash1)): # 不相等则n计数+1,n最终为相似度 if hash1[i]!=hash2[i]: n=n+1 return n img1 = cv2.imread('./foodimg/image0.jpg') img2 = cv2.imread('./foodimg/image1.jpg') hash1 = aHash(img1) hash2 = aHash(img2) n=cmpHash(hash1,hash2) print('均值哈希算法相似度:',n) n=classify_hist_with_split(img1,img2)#看的是image0和image2 print('三直方图算法相似度:',n) import os import cv2 from PIL import Image os.chdir(r'D:pythonclassvideo') print(os.getcwd()) #for f in os.listdir(r'D:pythonclassvideodanceimgdanceshot'): for i in range(1616): img1 = cv2.imread('./foodimg/image{}.jpg'.format(i)) img2 = cv2.imread('./foodimg/image{}.jpg'.format(i+1)) hash1 = aHash(img1) hash2 = aHash(img2) n = cmpHash(hash1,hash2) if (n>28): print('均值哈希算法相似度:',n/64) cv2.imwrite('./foodshot/image{}.jpg'.format(i+1),img2)
参数28时,效果如图:
5.4.2练习二参数15时,效果如图:可以发现镜头划分较为粗糙
将参数改为12,可以看到效果更好,但也会出现一些相似的镜头
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)