python去除视频中的logo_视频黑边去除算法(python+opencv)

黑边是指视频中存在的黑色或白色边框,这类边框存在于很多视频中,由于黑边的存在,哈希值的提取收到了它的干扰,尤其对于dhash来说,影响非常大,容易造成误判。在v1.0排重算法中,采用的黑边去除方法是opencv自带的函数,该函数对于包含logo的黑边处理效果很差,而绝大部分黑边中都包含视频logo,因此仍然存在大部分黑边未被去除的情况,所以手工重写黑边去除算法。

部分黑边情况如下图所示:

算法流程:

  ->->->

计算图像颜色直方图,求得颜色直方图的标准差,若标准差小于1024,则直接认定为不包含边框。(因为标准差越小说明颜色分布越均匀,越不可能出现纯色边框)

将图像转换为二值图像,这里利用OTSU算法确定分割阈值,OTSU算法能够好的分割前景色与背景色。

在二值图像的基础上,利用sobel算子计算出垂直与水平方向的边缘。

对计算得到的边缘图像统计分别统计横纵方向的边缘长度占比以及区域内的像素均值。

以中线折叠,取边缘最长的边,若其长度大于某一阈值,颜色均值不极端分布于黑色或白色,则认定该边缘为边框边缘。

取一个视频内所有边缘,做NMS,取得统一的边框边缘,利用该边缘切割所有该视频的截图,得到最终结果。

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值