關鍵幀提取——RCC提取關鍵幀(1)

最初

作爲第一篇,這裏介紹一下我對於關鍵幀提取算法效率的計算方法。

同時要考慮時間和正確率,兩者佔比爲4:64:6
滿分1010

對於66的部分,一旦取到了對應場景的關鍵幀,該部分+1+1
正確性應該是對於每個場景是等價的,所以最後取平均即可。

對於44的部分,我們計算多餘的佔需要得到的總關鍵幀的5倍的佔比,每個場景和100%100\%取最值。
最後取平均即可。
但是需要注意的是,只有拿到了66分,纔可能有44分;所以需要判斷一下。

最後兩者加權得到分數。

參考自
ANOVELVIDEOCOPYDETECTION《A NOVEL VIDEO COPY DETECTION
METHODBASEDONSTATISTICALANALYSISMETHOD BASED ON STATISTICAL ANALYSIS》

作者
HyeJeongChoHye-Jeong Cho等人

RCC

這裏介紹一下相關係數RCCRCC,用於表示兩者之間相關性。

RCC=16diffn(n21)RCC = 1 - \frac{6*diff}{n*(n^2-1)},越接近11表示越相關

這裏的差值,論文用的歐式距離。

那麼具體是利用什麼進行比較呢?

利用的是每張圖的灰度信息,得到灰度圖後,分成44個塊。
對於這44個塊,轉換成有序度量,然後進行比較。
具體就是對於這44個塊,求平均亮度值,然後排序,得到這44個點的排序後下標。

然後求相鄰RCC<kRCC<k的幀作爲關鍵幀。
這個kk是可以學習的。

最終得到的效率爲 5.765.76

代碼如下:

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)

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章