最初
作为第一篇,这里介绍一下我对于关键帧提取算法效率的计算方法。
同时要考虑时间和正确率,两者占比为
4
:
6
4:6
4:6
满分
10
10
10分
对于
6
6
6的部分,一旦取到了对应场景的关键帧,该部分
+
1
+1
+1
正确性应该是对于每个场景是等价的,所以最后取平均即可。
对于
4
4
4的部分,我们计算多余的占需要得到的总关键帧的5倍的占比,每个场景和
100
%
100\%
100%取最值。
最后取平均即可。
但是需要注意的是,只有拿到了
6
6
6分,才可能有
4
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
《ANOVELVIDEOCOPYDETECTION
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》
METHODBASEDONSTATISTICALANALYSIS》
作者
H
y
e
−
J
e
o
n
g
C
h
o
Hye-Jeong Cho
Hye−JeongCho等人
RCC
这里介绍一下相关系数 R C C RCC RCC,用于表示两者之间相关性。
R C C = 1 − 6 ∗ d i f f n ∗ ( n 2 − 1 ) RCC = 1 - \frac{6*diff}{n*(n^2-1)} RCC=1−n∗(n2−1)6∗diff,越接近 1 1 1表示越相关
这里的差值,论文用的欧式距离。
那么具体是利用什么进行比较呢?
利用的是每张图的灰度信息,得到灰度图后,分成
4
4
4个块。
对于这
4
4
4个块,转换成有序度量,然后进行比较。
具体就是对于这
4
4
4个块,求平均亮度值,然后排序,得到这
4
4
4个点的排序后下标。
然后求相邻
R
C
C
<
k
RCC<k
RCC<k的帧作为关键帧。
这个
k
k
k是可以学习的。
最终得到的效率为 5.76 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)