ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

第五节课·基于图像相似度比较分镜头

2021-10-21 09:59:28  阅读:179  来源: 互联网

标签:plt hash img cv2 第五节 哈希 图像 import 分镜头


目录

基本思路:

5.1 将视频打散为图片

5.2比较图像相似度

5.2.1 基于相等比较图像相似度

5.2.2 基于numpy计算图片是否相等

5.2.3 基于哈希(以均值哈希算法为例)

5.3 视频截取:ffmpeg

5.4 综合运用


基本思路:

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

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有