一、影像直方圖
完整代碼:
import cv2
import matplotlib.pyplot as plt
img= cv2.imread("girl.png")
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])
print(type(histb))
print(histb.size)
print(histb.shape)
plt.plot(histb, color="b")
plt.plot(histg, color="g")
plt.plot(histr, color="r")
plt.show()
運行結果:

函式使用:
cv2.calcHist(images, channels, mask, histSize, ranges[, hist[, accumulate ]]) ->hist
imaes 輸入的影像,要帶[]號
channels 選擇影像的通道,012對應著BGR,要帶[]號
mask 掩膜,是一個大小和image一樣的np陣列,其中把需要處理的部分指定為1,不需要處理的部分指定為0,一般設定為None,表示處理整幅影像
histSize 灰度級的個數,使用多少個bin,一般為256,要帶[]號
ranges 像素值的范圍,一般為[0,255],要帶[]號
二、視頻分鏡

(人工分鏡結果)
1、基于均值哈希
運行結果:

(少識別了兩個分鏡頭,誤識別了三個分鏡頭)
完整代碼:
import cv2
import numpy as np
import matplotlib.pyplot as plt
# 均值哈希演算法
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
# 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(549):
img1=cv2.imread('./pic2/image{}.jpg'.format(i))
img2=cv2.imread('./pic2/image{}.jpg'.format(i+1))
hash1 = aHash(img1)
hash2 = aHash(img2)
n = cmpHash(hash1, hash2)
if(n>22):
print('均值哈希演算法相似度:', n/64)
cv2.imwrite('./shot/image{}.jpg'.format(i+1),img2)
2、基于直方圖相似度
運行結果:

(少識別了兩個分鏡頭)
完整代碼:
import cv2
import numpy as np
import matplotlib.pyplot as plt
# 通過得到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) #cv2.split()拆分通道
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
for i in range(549):
img1=cv2.imread('./pic2/image{}.jpg'.format(i))
img2=cv2.imread('./pic2/image{}.jpg'.format(i+1))
n = classify_hist_with_split(img1,img2)
if(n<0.6):
cv2.imwrite('./shot2/image{}.jpg'.format(i+1),img2)
三、截取視頻(1分鐘)
完整代碼:
截取視頻前一分鐘:
ffmpeg -i input.mp4 -vcodec copy -acodec copy -ss 00:00:00 -to 00:01:00 cut.mp4 -y
截取視頻中間一分鐘:
ffmpeg -i input.mp4 -vcodec copy -acodec copy -ss 00:00:05 -t 00:01:00 cut.mp4 -y
或ffmpeg -i input.mp4 -ss 5 -c copy -t 60 cut.mp4 -y
引數含義:
-to 截到視頻的哪個時間點結束
-t 表示截取多長的時間
-vcodec copy 表示使用跟原視頻一樣的視頻編解碼器
-acodec copy 表示使用跟原視頻一樣的音頻編解碼器
問題記錄:
ffmpeg 為了加速,會使用關鍵幀技術(-ss 選項放在 -i 之前時), 有時剪切出來的結果在起止時間上未必準確,解決方法:ffmpeg -ss 00:01:00 -i video.mp4 -to 00:02:00 -c copy -copyts cut.mp4
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/325857.html
標籤:其他
