作业
本周作业:
1-视频分镜:基于均值哈希;基于直方图相似度。
2-在不同参数和视频(2-3个)的实验效果,用FFMPEG截取一段1分钟视频,测试
3-实验结果写帖子。
一、视频分镜
基于均值哈希;基于直方图相似度
均值哈希
import cv2
import numpy as np
import matplotlib.pyplot as plt
import os
os.getcwd()
os.chdir(r"D:\coding\2021python\lesson6")
os.getcwd()
# 均值哈希算法
def aHash(img):
plt.imshow(img)
plt.axis("off")
plt.show()
img=cv2.resize(img,(8,8)) # 缩放为8*8
plt.imshow(img)
plt.axis("off") #去掉坐标轴
plt.show()
#转化为灰度图
gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
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
# 哈希值对比
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
# 把视频打散为图片
import os
import cv2
import subprocess
v_path="video.mp4"
image_save="./video_img"
cap=cv2.VideoCapture(v_path)
#frame_count=cap.get(cv2.COLOR_BGR2RGB)
frame_count=cap.get(cv2.CAP_PROP_FRAME_COUNT)
for i in range(int(frame_count)):
_,img=cap.read()
#img = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
img=cv2.cvtColor(img,cv2.COLOR_BGR2RGB) #cv2.COLOR_RGB2HSV cv2.COLOR_BGR2GRAY cv2.COLOR_BGR2RGB
cv2.imwrite("./video_img/image{}.jpg".format(i),img)
from PIL import Image
for i in range(549):
img1=cv2.imread("./video_img/image{}.jpg".format(i))
img2=cv2.imread("./video_img/image{}.jpg".format(i+1))
hash1=aHash(img1)
hash2=aHash(img2)
n=cmpHash(hash1,hash2)
if (n>20):
print('均值哈希算法相似度:',n/64)
cv2.imwrite("./shot/image{}.jpg".format(i+1),img2)

基于直方图识别相似度
print(inspect.getdoc(cv2.calcHist))
定义
cv2.calcHist(images, channels, mask, histSize, ranges[, hist[, accumulate ]]) ->hist
maes:输入的图像
channels:选择图像的通道
mask:掩膜,是一个大小和image一样的np数组,其中把需要处理的部分指定为1,不需要处理的部分指定为0,一般设置为None,表示处理整幅图像
histSize:使用多少个bin(柱子),一般为256
ranges:像素值的范围,一般为[0,255]表示0~255
后面两个参数基本不用管。
注意,除了mask,其他四个参数都要带[]号。
显示图像直方图:
import cv2
import matplotlib.pyplot as plt
import os
# cv2 读取正常颜色图片
o = cv2.imread('./pic/htx.jpg')
o = cv2.cvtColor(o,cv2.COLOR_BGR2RGB)
#o = cv2.imread('./pic/htx.jpg',cv2.IMREAD_GRAYSCALE)
plt.imshow(o)
plt.show()
plt.hist(o.ravel(),256)
plt.show()

三通道直方图比较实现函数
opencv中的compareHist函数是用来计算两个直方图相似度,计算的度量方法有4个,分别为Correlation ( CV_COMP_CORREL )相关性,Chi-Square ( CV_COMP_CHISQR ) 卡方,Intersection ( method=CV_COMP_INTERSECT )交集法,Bhattacharyya distance ( CV_COMP_BHATTACHARYYA )常态分布比对的Bhattacharyya距离法。
ompareHist函数返回一个数值,相关性方法范围为0到1,1为最好匹配,卡方法和Bhattacharyya距离法是值为0最好,而交集法为值越大越好。
def show_hist(img):
# cv2读取图片
# img = cv2.imread(image)
# img = cv2.cvtColor(img,cv2.COLOR_BGR2RGB)
plt.imshow(img)
plt.axis("off")
plt.show()
# 显示图像三通道直方图
histb = cv2.calcHist([img], [0], None, [256], [0, 255])
histg = cv2.calcHist([img], [1], None, [256], [0, 255])
histr = cv2.calcHist([img], [2], None, [256], [0, 255])
plt.plot(histb, color="b")
plt.plot(histg, color="g")
plt.plot(histr, color="r")
plt.show()
#展示图片直方图
def create_rgb_hist(image):
h, w, c = image.shape
rgbHist = np.zeros([16*16*16, 1], np.float32)
bsize = 256/16
show_hist(image)
for row in range(h):
for col in range(w):
b = image[row, col, 0]
g = image[row, col, 1]
r = image[row, col, 2]
index = np.int(b/bsize)*16*16 + np.int(g/bsize)*16 + np.int(r/bsize)
rgbHist[np.int(index), 0] = rgbHist[np.int(index), 0]+1
def hist_compare(image1, image2):
hist1 = create_rgb_hist(image1)
hist2 = create_rgb_hist(image2)
match2 = cv2.compareHist(hist1, hist2, cv2.HISTCMP_CORREL)
return match2
for i in range(549):
img1=cv2.imread("./video_img/image{}.jpg".format(i))
img1= cv2.cvtColor(img1,cv2.COLOR_BGR2RGB)
img2=cv2.imread("./video_img/image{}.jpg".format(i+1))
img2= cv2.cvtColor(img2,cv2.COLOR_BGR2RGB)
# 通过上述文件中打散的图片
n=hist_compare(img1, img2)
if (n<0.7):
print('直方图相似度:',n)
cv2.imwrite("./shot2/image{}.jpg".format(i+1),img2)
程序实在运行太慢,先贴一张不同图片的卡法对比


二、ffmpeg截取视频
简单截取
ffmpeg -i oceans.mp4 -ss 0 -t 10 -codec copy cut.mp4
精确时间:
ffmpeg -ss 0 -t 10 -accurate_seek -i oceans.mp4 -codec copy cut.mp4
三、基础知识
打印函数全部功能 print(dir(Image)
查看该函数文档
import inspect
print(inspect.getdoc(Image.Image.convert))
print(inspect.getdoc(Image.open))
下次补充:
- python类的用法: http://c.biancheng.net/view/2283.html