关键帧提取——帧差法提取关键帧(2)

参考自
《 K e y F r a m e E x t r a c t i o n o f O n l i n e V i d e o B a s e d o n O p t i m i z e d F r a m e D i f f e r e n c e 》 《Key Frame Extraction of Online Video Based on Optimized Frame Difference》 KeyFrameExtractionofOnlineVideoBasedonOptimizedFrameDifference

作者
H u a y o n g L i u , W e n t i n g M e n g Huayong Liu, Wenting Meng HuayongLiu,WentingMeng等人

帧差

首先对帧间进行平滑,减少过小的差异。
其次计算帧间差分均值。
最后计算局部最值,因为量过大,所以需要设计一个带局部最值窗口的求极值方法。
准确说就是,仅当你是 [ l , r ] [l,r] [l,r]区间的最值是你才是我们需要的极值。

所有极值点都是关键帧。
最后得到的分数是 6.89 6.89 6.89

gaoimport 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;#一帧多少秒
len_windows = 0
local_windows = 0
 
def smooth(swift_img,windows):
    r = swift_img.shape[1]
    c = swift_img.shape[2]
    for i in range(r):
        for j in range(c):
            L = swift_img[:,i,j]
            L = np.convolve(L,np.ones(windows),'same')
            swift_img[:,i,j] = L
    return swift_img

def get_block(img):
    img = np.array(img)
    return img

def dif(img1,img2):
    diff = img1 - img2
    diff = np.abs(np.array(diff))
    diff = diff.mean()
    return diff
    
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,local_windows):
    L = []
    L.append(0)
    for i in range(swift_img.shape[0]-1):
        temp = dif(swift_img[i],swift_img[i+1])
        L.append(temp)
    L = np.array(L)
    TL = []
    for i in range(L.shape[0]):
        l = i - local_windows // 2
        r = i + local_windows // 2
        l = max(l,0)
        r = min(r,L.shape[0])
        if i == l + np.argmax(L[l:r]):
            TL.append(True)
        else:
            TL.append(False)
#    print(TL)
    TL = np.array(TL)
    return TL

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
    right = 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 j == 0 :
                print(i)
            if i + ansl[l] >= ll and i + ansl[l] <= rr:
                num += 1
        if num == 0:
            rate.append(0.0)
        else:
            right += 1
            if num == 1:
                rate.append(6.0)
                continue
            add += num - 1
            rate.append(6.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(right)
    ret += 4 * (1 - add) * right / (r - l + 1)#总共帧数中只有正确的部分才考虑时间因素。
    print("评分是:")
    print(ret)
    return ret

def study():
    window = 1
    local = 2
    mmax = 0
    lindex = 4
    rindex = 10
    for i in range(10):
        tmp = 1 + i
        for j in range(10):
            Tmp = 2 + j
            print("当前参数: "+"卷积窗口"+str(tmp)+"最值窗口"+str(Tmp))
            tmp_img = get_img(ansl[lindex],ansr[rindex])
            tmp_img = smooth(tmp_img,tmp)
            tmp_L = get_key_frame(tmp_img,Tmp)
            ttmp = cal_ans(tmp_L,lindex,rindex)
            if ttmp > mmax:
                window = tmp
                local = Tmp
                mmax = ttmp
            print("分割线--------------------")
    return window,local

len_windows,local_windows = study()
print("最终:")
print(len_windows)
print(local_windows)
print("")

swift_img = get_img()
swift_img = smooth(swift_img,len_windows)
cal_L= get_key_frame(swift_img,local_windows)
cal_ans(cal_L,0,ansl.shape[0]-1)
#preserve(cal_L)


#结果:
#6.89
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值