最初
作爲第一篇,這裏介紹一下我對於關鍵幀提取算法效率的計算方法。
同時要考慮時間和正確率,兩者佔比爲
滿分分
對於的部分,一旦取到了對應場景的關鍵幀,該部分
正確性應該是對於每個場景是等價的,所以最後取平均即可。
對於的部分,我們計算多餘的佔需要得到的總關鍵幀的5倍的佔比,每個場景和取最值。
最後取平均即可。
但是需要注意的是,只有拿到了分,纔可能有分;所以需要判斷一下。
最後兩者加權得到分數。
參考自
作者
等人
RCC
這裏介紹一下相關係數,用於表示兩者之間相關性。
,越接近表示越相關
這裏的差值,論文用的歐式距離。
那麼具體是利用什麼進行比較呢?
利用的是每張圖的灰度信息,得到灰度圖後,分成個塊。
對於這個塊,轉換成有序度量,然後進行比較。
具體就是對於這個塊,求平均亮度值,然後排序,得到這個點的排序後下標。
然後求相鄰的幀作爲關鍵幀。
這個是可以學習的。
最終得到的效率爲
代碼如下:
import numpy as np
import cv2
ansl = [1,94,132,154,162,177,222,236,252,268,286,310,322,255,373,401,
423,431,444,498,546,594,627,681,759,800,832,846,932,1235,1369,1438,1529,1581,1847]
ansr = [93,131,153,161,176,221,235,251,267,285,309,321,354,372,400,
422,430,443,497,545,593,626,680,758,799,831,845,931,1234,1368,1437,
1528,1580,1846,2139]#關鍵幀區間
ansl = np.array(ansl)
ansr = np.array(ansr)
cap = cv2.VideoCapture('D:/ai/CV/pyt/1.mp4')
Frame_rate = cap.get(5)#一秒多少幀
Frame_number = cap.get(7)#幀數
Frame_time = 1000 / Frame_rate;#一幀多少秒
def get_block(img):
img = np.array(img)
row = img.shape[0] // 2
col = img.shape[1] // 2
L = []
for i in range(2):
for j in range(2):
L.append(np.sum(img[i*row:(i+1)*row,j*col:(j+1)*col])/(row*col))
L = np.array(L)
L = L.ravel()
L = np.argsort(L)
return L
def RCC(img1,img2):
diff = 0
for i in range(4):
diff += np.power(img1[i]-img2[i],2)
rcc = 1 - 6 * diff / (4 * (4 ** 2 - 1))
return rcc
def get_img(now_time = 0,get_number = Frame_number):#便於算法學習
swift_img = []#轉換後
index = 0#標記第幾個幀
time = now_time#當前時間
while (cap.isOpened()):
cap.set(cv2.CAP_PROP_POS_MSEC,time)
ret,img = cap.read()#獲取圖像
if not ret:
break
img0 = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)#轉換成灰度圖
img1 = get_block(img0)
swift_img.append(img1)
time += Frame_time
index += 1
if index >= get_number:
break
# if index % 50 ==0:
# print("當前到達"+str(index))
swift_img = np.array(swift_img)
return swift_img
def get_key_frame(swift_img,standard):
L = []
for i in range(swift_img.shape[0]-1):
tmp = RCC(swift_img[i],swift_img[i+1])
if tmp < standard:
L.append(True)
else:
L.append(False)
L.append(False)
L = np.array(L)
return L
def preserve(L):
num = 0
time = 0
for i in range(L.shape[0]):
if L[i] == False:
continue
num += 1
cap.set(cv2.CAP_PROP_POS_MSEC,time)
ret,img = cap.read()#獲取圖像
cv2.imwrite('./1.1/{0:05d}.jpg'.format(num),img)#保存關鍵幀
time += Frame_time
def cal_ans(cal_L,l,r):
rate = []
add = 0
for j in range(ansl.shape[0]):
num = 0
if not (l <= j and j <= r):
continue
ll = ansl[j]
rr = ansr[j]
for i in range(cal_L.shape[0]):
if cal_L[i] == False:
continue
if i + ansl[l] >= ll and i + ansl[l] <= rr:
num += 1
if num == 0:
rate.append(0.0)
else:
if num == 1:
rate.append(4.0)
continue
add += num - 1
rate.append(4.0)
rate = np.array(rate)
ret = np.sum(rate) / rate.shape[0]
print("多餘的個數:")
print(add)
add = add / (5 * (r - l + 1))
add = min(add , 1)
print("多餘的佔比:")
print(add)
print("正確的評分:")
print(ret)
ret += 6 * (1 - add)
print("評分是:")
print(ret)
return ret
def study():
stdad = 1
mmax = 0
lindex = 4
rindex = 10
for i in range(11):
tmp = 1.0 - 0.05 * i
print("當前參數: "+str(tmp))
tmp_img = get_img(ansl[lindex],ansr[rindex])
tmp_L = get_key_frame(tmp_img,tmp)
ttmp = cal_ans(tmp_L,lindex,rindex)
if ttmp > mmax:
stdad = tmp
mmax = ttmp
print("分割線--------------------")
return stdad
standard = study()
print("最終參數"+str(standard))
swift_img = get_img()
cal_L= get_key_frame(swift_img,standard)
cal_ans(cal_L,0,ansl.shape[0]-1)
#preserve(cal_L)