任务
在Windows10系统下,用python,在jupyter notebook,对week5中“将视频每一帧保存成图像”的基础上,通过自定义的均值哈希算法、各通道直方图两种方法对该有序系列图片进行相似度计算,拣出差距大于一定值的图片另存,以判断原视频的镜头数。
应用ffmpeg在长视频中截取片段,转换为图像,估计镜头数。
Ⅰ均值哈希算法
导入所需各库。
os和shutil两个库用来相互辅助完成新建、删除、遍历文件或文件夹的功能。
os.remove(r"里面填文件路径"):删文件(慎用,错了该文件就找不回来了)
os.makedirs("./p"):当前工作路径下新建文件夹p
os.listdir("./p"):遍历p文件夹内的文件,返回内含文件夹内各文件的列表 os.removedirs("./p"):当前工作路径下删除空文件夹p(文件夹必须为空,否则报错)
shutil.rmtree("./p",ignore_errors=True)#删除文件夹,非空也能删除
import cv2
import numpy as np
import matplotlib.pyplot as plt
from PIL import Image
import inspect
import os
import shutil
定义函数,转换图像表达式:
更改图片规格为8*8,转为灰度图像
遍历图片8*8每个格子,并叠加每个格子的像素,求其均值
遍历图片8*8每个格子,并判断像素值与均值的大小,大于均值返回1,小于均值返回0,最后得到一个64位的二进制数
彩色图像img[i,j,c]:i表示图片的行数,j表示图片的列数,c表示图片的通道数(RGB三通道分别对应0,1,2)。坐标是从左上角开始。
灰度图像gray[i,j]:返回图像第i行第j列的像素值
def aHash(img):
#缩放为8x8
"""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为hash 值初值为''
s=0
hash_str=""
#遍历累加求像素和
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
定义函数,比较两个图像表达式的区别,并得出图像差别大小,返回值gap越大,差别越大
if语句,若两图hash长度不同,返回-1表示传参出错
for循环,遍历两张图像64位二进制数每一位,判断其区别,若不同,则gap+1,表示差别更大
def cmpHash(hash1,hash2):
gap=0
#hash长度不同则返回-1代表传参出错
if len(hash1)!=len(hash2):
return -1
for i in range(len(hash1)):
if hash1[i]!=hash2[i]:
gap=gap+1
return gap
删除当前工作路径下名为p的文件夹并生成一个空文件夹p,以防同段代码多次运行导致文件夹内文件混乱
遍历保存了有序系列图像的文件夹pic
将文件夹pic中第一张图片同名保存至文件夹p
shutil.rmtree("./p",ignore_errors=True)
os.makedirs("./p")
filelist=os.listdir("./pic")
cv2.imwrite(os.path.join("./p",filelist[0]),img1)
方法1:遍历比较时不是相邻两张图片比较,而是相邻两张显示足够相似时,左图不变,右图从第一张图开始遍历,比较两张图,直到相似度过低时,保存右图,并将当前右图更换为左图,而右图继续遍历,直至遍历结束。
for i in range(len(filelist)-1):
img2=cv2.imread("./pic/"+"image{}".format(i+1)+".jpg")
ga