Advertisement

【python】利用哈希直方图截取图像相似度&FFmpeg截取视频

阅读量:

(一)哈希&直方图相似度

一、导入视频并抽帧

1. 利用os.chdir定位文件夹位置

2. 导入视频,并将抽帧出来的视频放在文件夹里(文件夹需要提前新建)

复制代码
 import os

    
 import cv2
    
 import subprocess
    
  
    
 os.chdir('/Users/liruiying/Documents/pythonclass2021')
    
 v_path='vm1.mp4'
    
 image_save='/Users/liruiying/Documents/pythonclass2021/vm_pic'
    
  
    
 cap=cv2.VideoCapture(v_path)
    
 frame_count=cap.get(cv2.CAP_PROP_FRAME_COUNT)
    
  
    
 for i in range(int(frame_count)):
    
     _,img=cap.read()
    
     cv2.imwrite('/Users/liruiying/Documents/pythonclass2021/vm_pic/image{}.jpg'.format(i),img)

二、哈希算法&直方图比较相似度

复制代码
 import cv2

    
 import numpy as np
    
 import matplotlib.pyplot as plt
    
 import os
    
 os.chdir(r'/Users/liruiying/Documents/pythonclass2021')
    
  
    
  
    
 # 均值哈希算法
    
 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为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
    
  
    
  
    
  
    
 # 通过得到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, 255.0])
    
     hist2 = cv2.calcHist([image2], [0], None, [256], [0.0, 255.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
    
  
    
 for i in range(825):
    
     img1=cv2.imread('./vm_pic/image{}.jpg'.format(i))
    
     img2=cv2.imread('./vm_pic/image{}.jpg'.format(i+1))
    
     hash1=aHash(img1)
    
     hash2=aHash(img2)
    
     n=cmpHash(hash1,hash2)
    
     if(n>15):
    
     print('均值哈希算法相似度:',n/64)
    
     cv2.imwrite('./vm_shot1/image{}.jpg'.format(i+1),img2)
    
     
    
  
    
 n = classify_hist_with_split(img1, img2)
    
 print('三直方图算法相似度:', n)

运行结果如下:

问题与思考:只能前一帧和后一帧相比较,加入前后画面类似但中间插入了一段其他画面,则无法进行相似度比较并删减。

(二)FFmpeg截取视频

一、MAC电脑存在问题

在研究之后,发现MAC电脑的FFmpeg还是存在问题,暂时还没有研究出来该怎么调整

于是先找PC的电脑跑出来运行的结果。

原视频:


全部评论 (0)

还没有任何评论哟~