关键帧提取——RCC提取关键帧(1)

最初

作为第一篇,这里介绍一下我对于关键帧提取算法效率的计算方法。

同时要考虑时间和正确率,两者占比为 4 : 6 4:6
满分 10 10

对于 6 6 的部分,一旦取到了对应场景的关键帧,该部分 + 1 +1
正确性应该是对于每个场景是等价的,所以最后取平均即可。

对于 4 4 的部分,我们计算多余的占需要得到的总关键帧的5倍的占比,每个场景和 100 % 100\% 取最值。
最后取平均即可。
但是需要注意的是,只有拿到了 6 6 分,才可能有 4 4 分;所以需要判断一下。

最后两者加权得到分数。

参考自
A N O V E L V I D E O C O P Y D E T E C T I O N 《A NOVEL VIDEO COPY DETECTION
M E T H O D B A S E D O N S T A T I S T I C A L A N A L Y S I S METHOD BASED ON STATISTICAL ANALYSIS》

作者
H y e J e o n g C h o Hye-Jeong Cho 等人

RCC

这里介绍一下相关系数 R C C RCC ,用于表示两者之间相关性。

R C C = 1 6 d i f f n ( n 2 1 ) RCC = 1 - \frac{6*diff}{n*(n^2-1)} ,越接近 1 1 表示越相关

这里的差值,论文用的欧式距离。

那么具体是利用什么进行比较呢?

扫描二维码关注公众号,回复: 10414537 查看本文章

利用的是每张图的灰度信息,得到灰度图后,分成 4 4 个块。
对于这 4 4 个块,转换成有序度量,然后进行比较。
具体就是对于这 4 4 个块,求平均亮度值,然后排序,得到这 4 4 个点的排序后下标。

然后求相邻 R C C < k RCC<k 的帧作为关键帧。
这个 k k 是可以学习的。

最终得到的效率为 5.76 5.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)

发布了203 篇原创文章 · 获赞 17 · 访问量 2万+

猜你喜欢

转载自blog.csdn.net/mxYlulu/article/details/105182763