黑边是指视频中存在的黑色或白色边框,这类边框存在于很多视频中,由于黑边的存在,哈希值的提取收到了它的干扰,尤其对于dhash来说,影响非常大,容易造成误判。在v1.0排重算法中,采用的黑边去除方法是opencv自带的函数,该函数对于包含logo的黑边处理效果很差,而绝大部分黑边中都包含视频logo,因此仍然存在大部分黑边未被去除的情况,所以手工重写黑边去除算法。
部分黑边情况如下图所示:
算法流程:
import os
import cv2
import numpy as np
from io import BytesIO
from PIL import Image
import base64
class BorderRm():
def nms(self,boxes,overlap=0.8):
boxes = [[i[0],i[2],i[1],i[3],s] for i,s in boxes.items()]
boxes = sorted(boxes,key=lambda N:N[4])
if not boxes:
pick = []
else:
trial = np.zeros((len(boxes),5),dtype=np.float32)
trial[:] = boxes[:]
x1 = trial[:,0]
y1 = trial[:,1]
x2 = trial[:,2]
y2 = trial[:,3]
score = trial[:,4]
area = (x2-x1+1)*(y2-y1+1)
I = np.argsort(score)
pick = []
while (I.size!=0):
last = I.size
i = I[last-1]
pick.append(i)
suppress = [last-1]
for pos in range(last):
j = I[pos]
xx1 = max(x1[i],x1[j])
yy1 = max(y1[i],y1[j])
xx2 = min(x2[i],x2[j])
yy2 = min(y2[i],y2[j])
w = xx2-xx1+1
h = yy2-yy1+1
if (w>0 and h>0):
o = w*h/max(area[i],area[j])
if (o >overlap):
if pos != i:
boxes[i][4] += boxes[pos][4]
suppress.append(pos)
I = np.delete(I,suppress)
newBox = []
for i in pick:
newBox.append(boxes[i])
newBox = sorted(newBox,key=lambda N:N[4],reverse=True)
return newBox[0][:4]
def remove_border_imgs(self,imgs):
borders = {}
for img in imgs:
img = Image.open(BytesIO(base64.b64decode(img))).convert("RGB")
img = img.convert('RGB')
im = cv2.cvtColor(np.asarray(img),cv2.COLOR_RGB2BGR)
im = cv2.cvtColor(im, cv2.COLOR_BGR2GRAY)
(x1,x2),(y1,y2) = self.sobel(im)
if (x1,x2,y1,y2) not in borders:
borders[(x1,x2,y1,y2)] = 1
else:
borders[(x1,x2,y1,y2)] += 1
x1,y1,x2,y2 = self.nms(borders)
return x1,y1,x2,y2
def detectBorder(self,im,ori,width,length,side):
border = {}
if side == 'X':
im = im.T
ori = ori.T
for i,ix in enumerate(im):
border[i] = (np.sum(ix)*0.003921568627451,np.sum(ori[i])*0.003921568627451)
border = self.checkborder(border,width,length,side)
return border
def checkborder(self,border,width,length,side):
border = [(k,border[k]) for k in sorted(border.keys())]
Nborder = []
colorSum = 0
for i in range(int(length*0.375)):
colorSum += border[i][1][1]+border[length-i-1][1][1]
Nborder.append((i,border[i][1][0]+border[length-i-1][1][0],colorSum))
res = sorted(Nborder,key=lambda N:N[1],reverse=True)[0]
cw = res[0]
Bvalue = res[1]*0.5
Cvalue = res[2]*0.5/(cw+1)
if side == 'Y':
B = 0.30
C = 0.40
else:
B = 0.40
C = 0.40
if Bvaluewidth*C and Cvalue