第五节课·基于图像相似度比较分镜头
作者:互联网
目录
基本思路:
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:\pythonclass\video')
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练习一
代码如下:
效果如图:
标签:plt,hash,img,cv2,第五节,哈希,图像,import,分镜头 来源: https://blog.csdn.net/qq_61995860/article/details/120879812