視頻水印自動識別和去除

背景

在之前學習爬蟲項目中憋他,得到的部分視頻是有水印的进陡,因此有能通過比較好的技術手段實現(xiàn)水印去除的需求。一般情況下萝衩,如果能獲取到無水印的原始素材是最好回挽,但某些網(wǎng)站本身的原始素材就是加了水印。對于這種情況猩谊,少量可以通過某些視頻剪輯軟件完成水印去除千劈,但對于大量素材,依賴人工完成是不現(xiàn)實的牌捷。

描述

這篇文章將提供一種方法墙牌,描述在特定類型視頻中,使用技術手段完成水印去除的實現(xiàn)暗甥,僅供參考學習喜滨,請合理使用,避免法律風險淋袖。

主要的實現(xiàn)方式其實非常簡單鸿市,主要是各種現(xiàn)有工具的整合,最終也達到了比較好的效果即碗。在限定品類之后,去除效果評估合格率達到了97%陌凳。

調研

在網(wǎng)上調研之后剥懒,主要有以下可參考的實現(xiàn),可以看到合敦,他們各自有不同的優(yōu)勢和缺點初橘。

  1. 高端大氣上AI
    首先AI有比較高的接入成本和學習門檻,而且本身有些玄學充岛。拋開算法保檐,最終的效果還是依賴輸入樣本的訓練。再回到我們素材自身崔梗,不同作者其水印會是變化的(id為水右怪弧)。算法訓練蒜魄,其實獲得準確位置的能力有待確定扔亥。
    總結缺點: 依賴眾多,需要訓練谈为,Id+logo變化的情況預計訓練模型不會容易適配旅挤,效果也不理想。

  2. ffmpeg delogo
    實際是在水印位置添加濾鏡伞鲫,類似毛玻璃效果粘茄。這種是比較直接的方式,但問題的核心變成了如何獲取水印的位置秕脓。還有個問題就是柒瓣,ffmpeg delogo 的效果在不同視頻素材不穩(wěn)定儒搭。例如,如果一個視頻幀水印位置畫面內容比較多嘹朗,去除水印后會比較明顯师妙。不過一般情況下,水印在右上或者左上屹培,畫面內容相對較少默穴。
    總結缺點:產生模糊區(qū)域,需要確定位置和大小褪秀。

  3. 蒙版+opencv + python 逐幀處理
    可否將視頻處理成圖片蓄诽,然后再按每張圖片來處理?當然理論是可行的媒吗,這就將問題變成了圖片去水印仑氛,而且像openCV有比較成熟的去水印算法。但是幾個問題闸英。
    首先是openCV的圖片去水印需要一個蒙版锯岖,即有個純色+水印的圖片,當然也不太適合不同視頻水印logo變化的情況甫何。按每個視頻創(chuàng)建蒙版也是沒法做成自動化的出吹。

另一個是視頻處理成圖片后,內容過大辙喂。測試中捶牢,一個19MB的1080P60hz視頻,處理成圖片變成了3GB大小巍耗,而且每幀處理也比較耗時秋麸,更不說合并成視頻的耗時。
缺點明確: 生成蒙版+逐幀處理+耗時較大

  1. cv 獲取固定圖標+ id生成位置坐標
    最后一種方案是折衷的方式炬太,也是最終采用的灸蟆。首先,水印的獲取仍然使用openCV娄琉,不過是采用CV的圖像識別次乓。對于視頻,也不是按照所有幀的方式孽水,而是隨機得選取某些幀獲取截圖票腰,然后用cv去拿到水印坐標。這里有個前提女气,是水印中有部分是不變的杏慰,比如logo。先人工將這部分摳圖下來,然后代入CV做識別缘滥,拿到了logo的坐標轰胁。因為不同幀會有變化,造成CV失敗的誤差朝扼,需要在失敗的坐標中篩選成功率高的赃阀。
    然后由于水印是 logo+id的形式,再根據(jù)id的字數(shù)和字體字號占的像素數(shù)擎颖,通過之前獲取的坐標算出水印的大小榛斯。如此我們就知道了水印的位置和大小,就可以使用ffmpeg delogo做去除了搂捧。

總結驮俗,最后實際是采用了第四種方案和第二種的結合,當然這也是根據(jù)具體場景綜合考慮的允跑,未必就是通用和最優(yōu)的實現(xiàn)王凑。

技術方案

描述

如上面的介紹,最終識別部分方案可以匯總成如下的流程:既然已經(jīng)知道了水印的位置和大小聋丝,就可以使用ffmpeg delogo 的方式來去除索烹。絕大部分視頻的處理效果是可以接受的。

摳圖獲取統(tǒng)一logo ---> 視頻隨機分幀 ---> CV識別logo坐標 ---> 根據(jù)視頻作者昵稱計算水印大小 ---> ffmpeg delogo去除水印弱睦。

計算水印位置大小核心代碼

import cv2
from matplotlib import pyplot as plt

# source=input('source:')
# tpl=input('template:')
source = '/export/data/晴天獨奏/mask/1.png'
tpl = 'mark_bili_1280.png'

img = cv2.imread(source, 0)
img2 = img.copy()
template = cv2.imread(tpl, 0)
# 非1080*1920需要等比例縮放
w, h = template.shape[::-1]

ow, oh = img.shape[::-1]

# # All the 6 methods for comparison in a list
methods = ['cv2.TM_CCOEFF', 'cv2.TM_CCOEFF_NORMED', 'cv2.TM_CCORR',
           'cv2.TM_CCORR_NORMED', 'cv2.TM_SQDIFF', 'cv2.TM_SQDIFF_NORMED']
#
# methods = ['cv2.TM_CCOEFF_NORMED']
for meth in methods:
    img = img2.copy()
    method = eval(meth)

    # Apply template Matching
    res = cv2.matchTemplate(img, template, method)
    min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(res)

    # If the method is TM_SQDIFF or TM_SQDIFF_NORMED, take minimum
    if method in [cv2.TM_SQDIFF, cv2.TM_SQDIFF_NORMED]:
        top_left = min_loc
    else:
        top_left = max_loc
    bottom_right = (top_left[0] + w, top_left[1] + h)
    cv2.rectangle(img, top_left, bottom_right, 255, 1)
    print('x={},y={},w={},h={}'.format(top_left[0], top_left[1], bottom_right[0]-top_left[0], bottom_right[1] - top_left[1]))

    plt.subplot(121), plt.imshow(res, cmap='gray')
    plt.title('Matching Result'), plt.xticks([]), plt.yticks([])
    plt.subplot(122), plt.imshow(img, cmap='gray')
    plt.title('Detected Point'), plt.xticks([]), plt.yticks([])
    plt.suptitle(meth)

    plt.show()

比較識別效果

不同算法的比較

最終去除效果對比

去除后

去除前

視頻分幀代碼


import os
import sys

import cv2

video_name = sys.argv[1]
if video_name is None:
    print("input video name!")
    exit(1)

com = 'ffmpeg -ss 10 -i {}  -f image2  -vframes 1 -y  frame.png'.format(video_name)
os.system(com)

cv2.namedWindow('frame', 0)
img = cv2.imread('frame.png')
cv2.imshow('frame', img)
cv2.waitKey(0)

批量匹配水印

用于在批量的截圖中標記識別的水印术荤,并打印出坐標


import os

import cv2

# source=input('source:')
# tpl=input('template:')
tpl = '/export/code/github/demo/src/test/resources/mark/mark_bili_1280-1.png'
template = cv2.imread(tpl, 0)
# 非1080*1920需要等比例縮放
w, h = template.shape[::-1]

# # All the 6 methods for comparison in a list
# methods = ['cv2.TM_CCOEFF', 'cv2.TM_CCOEFF_NORMED', 'cv2.TM_CCORR',
#            'cv2.TM_CCORR_NORMED', 'cv2.TM_SQDIFF', 'cv2.TM_SQDIFF_NORMED']
#

dir = '/export/data/BV1dT4y1E7w3/out/'
# dir = '/export/code/github/demo/data/out/'
files = []
for f in os.walk(dir):
    f = f[2]
    for x in f:
        if '.png' not in x:
            continue
        files.append(x)
    break
count = 1
for f in files:
    source = dir + f
    img = cv2.imread(source, 0)

    img2 = img.copy()

    ow, oh = img.shape[::-1]
    meth = 'cv2.TM_CCOEFF_NORMED'
    img = img2.copy()
    method = eval(meth)

    # Apply template Matching
    res = cv2.matchTemplate(img, template, method)
    min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(res)

    # If the method is TM_SQDIFF or TM_SQDIFF_NORMED, take minimum
    if method in [cv2.TM_SQDIFF, cv2.TM_SQDIFF_NORMED]:
        top_left = min_loc
    else:
        top_left = max_loc
    bottom_right = (top_left[0] + w, top_left[1] + h)
    cv2.rectangle(img, top_left, bottom_right, 255, 1)
    cv2.imwrite(source + ".mark.png", img)
    print('id:{} x={}:y={}:w={}:h={}'.format(count, top_left[0], top_left[1], bottom_right[0] - top_left[0], bottom_right[1] - top_left[1]))
    count = count + 1

遇到的問題

  • 1.識別錯位

錯位有以下幾個原因造成。

  • 1.1 部分視頻分辨率不統(tǒng)一每篷,如變成1280*720。 解決辦法是額外使用該分辨率下的logo 模板做CV識別端圈。
  • 1.2 視頻網(wǎng)站在某個時間之后更換了logo樣式焦读。 解決辦法是只選取固定時間點之后的視頻。
  • 1.3 水印中作者昵稱部分舱权,因為中英文字體大小矗晃,造成水印去除殘留。 解決辦法是根據(jù)不同字體用對應不同像素計算水印大小宴倍。以及多加些額外的冗余值张症,保證去除范圍比實際水印范圍大。
  • 1.4 其他識別錯位鸵贬。有極少數(shù)視頻因為內容的原因俗他,隨機取的幀無法正確得到水印位置勒叠。解決方法是設置閾值佃牛,比如隨機20幀,只有某個坐標重復達到或超過5次风响,才作為有效坐標,否則羡亩,重新截圖分幀摩疑,再次失敗。實際驗證效果不是很理想畏铆,遂超過次數(shù)后雷袋,判斷為失敗,過濾掉辞居。還有就是本身沒有水印楷怒,這種目前只能以來人工介入。
  1. ffmpeg 消耗CPU資源過高
    這個主要是開始沒有太注意ffmpeg的參數(shù)速侈,默認占滿全部CPU率寡,導致開始時候卡頓。 可以通過-threads參數(shù)設置占用的CPU
  2. 視頻水印去除后毛玻璃效果過于明顯
    這種情況因為完全和視頻內容有關系倚搬,目前的方案依賴ffmpeg冶共,暫時無解。能想到的是優(yōu)化ffmpeg的去水印算法每界,非現(xiàn)實快速可達的方案捅僵。
  3. 項目中都是java,有沒有方法將如上包括openCV, ffmpeg的調用使用java實現(xiàn)眨层?
    這算是個嘗試庙楚,當然答案是可以實現(xiàn)的,有現(xiàn)成的Bytedeco趴樱,可以避免自己寫大量命令行調用馒闷。

總結

以上就是本篇文章的所有內容,限于篇幅叁征,部分細節(jié)沒有全部補充纳账。過程中某些情況下,雖然已經(jīng)知道了方法捺疼,但是仍然需要花大量的時間去調試和驗證才能知道最終的效果疏虫。當然最后也是在不斷的實踐下有了明顯的提升。如之前所說啤呼,在控制輸入樣本的前提下卧秘,比如只選擇右上角水印,盡量保證視頻分辨率一致等官扣,最終的評估合格率達到了97%翅敌,還是令人滿意的。

參考資料

  1. ziweipolaris/watermark-removal: 通過水印減除方法去掉視頻中的水印醇锚,快速但不完美
  2. 基于GAN的圖像水印去除器哼御,效果堪比PS高手 – 閃念基因 – 個人技術分享
  3. 毫秒級圖像去噪坯临!新AI系統(tǒng)完美去水印恋昼! - 云+社區(qū) - 騰訊云
  4. 去噪看靠、去水印、超分辨率液肌,這款不用學習的神經(jīng)網(wǎng)絡無所不能 - 云+社區(qū) - 騰訊云
  5. 【深度學習去水印】- CSDN
  6. 去噪挟炬、去水印、超分辨率嗦哆,這款不用學習的神經(jīng)網(wǎng)絡無所不能 | 機器之心
  7. [論文分享(一)] 水印自動去除(上)---水印的自動識別和特征提取 - 知乎
  8. 短視頻解析谤祖,去水印原理整理匯總-博客
  9. Python實現(xiàn)超簡單【抖音】無水印視頻批量下載fei347795790的博客-CSDN博客抖音批量下載 無水印
  10. 接近無損的視頻去水印方法
  11. Python OpenCV去除圖片水印_XerCis的博客-CSDN博客_cv2 去除水印
  12. python利用opencv去除水印方法 - 菲菲菲菲菲常新的新手 - 博客園
  13. 兩種Python基于OpenCV的固定位置半透明水印去除方案 - 麥拂沙的個人空間 - OSCHINA
  14. 基于python的圖片修復程序-可用于水印去除 - 簡書
  15. JavaCV入門示例及UnsatisfiedLinkError異常踩坑記錄
  16. Bytedeco - Home
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市老速,隨后出現(xiàn)的幾起案子粥喜,更是在濱河造成了極大的恐慌,老刑警劉巖橘券,帶你破解...
    沈念sama閱讀 212,718評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件额湘,死亡現(xiàn)場離奇詭異,居然都是意外死亡旁舰,警方通過查閱死者的電腦和手機锋华,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,683評論 3 385
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來箭窜,“玉大人毯焕,你說我怎么就攤上這事』怯#” “怎么了纳猫?”我有些...
    開封第一講書人閱讀 158,207評論 0 348
  • 文/不壞的土叔 我叫張陵,是天一觀的道長竹捉。 經(jīng)常有香客問我续担,道長,這世上最難降的妖魔是什么活孩? 我笑而不...
    開封第一講書人閱讀 56,755評論 1 284
  • 正文 為了忘掉前任,我火速辦了婚禮乖仇,結果婚禮上憾儒,老公的妹妹穿的比我還像新娘。我一直安慰自己乃沙,他們只是感情好起趾,可當我...
    茶點故事閱讀 65,862評論 6 386
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著警儒,像睡著了一般训裆。 火紅的嫁衣襯著肌膚如雪眶根。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 50,050評論 1 291
  • 那天边琉,我揣著相機與錄音属百,去河邊找鬼。 笑死变姨,一個胖子當著我的面吹牛族扰,可吹牛的內容都是我干的。 我是一名探鬼主播定欧,決...
    沈念sama閱讀 39,136評論 3 410
  • 文/蒼蘭香墨 我猛地睜開眼渔呵,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了砍鸠?” 一聲冷哼從身側響起扩氢,我...
    開封第一講書人閱讀 37,882評論 0 268
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎爷辱,沒想到半個月后录豺,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,330評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡托嚣,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 36,651評論 2 327
  • 正文 我和宋清朗相戀三年巩检,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片示启。...
    茶點故事閱讀 38,789評論 1 341
  • 序言:一個原本活蹦亂跳的男人離奇死亡兢哭,死狀恐怖,靈堂內的尸體忽然破棺而出夫嗓,到底是詐尸還是另有隱情迟螺,我是刑警寧澤,帶...
    沈念sama閱讀 34,477評論 4 333
  • 正文 年R本政府宣布舍咖,位于F島的核電站矩父,受9級特大地震影響,放射性物質發(fā)生泄漏排霉。R本人自食惡果不足惜窍株,卻給世界環(huán)境...
    茶點故事閱讀 40,135評論 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望攻柠。 院中可真熱鬧球订,春花似錦、人聲如沸瑰钮。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,864評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽浪谴。三九已至开睡,卻和暖如春因苹,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背篇恒。 一陣腳步聲響...
    開封第一講書人閱讀 32,099評論 1 267
  • 我被黑心中介騙來泰國打工扶檐, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人婚度。 一個月前我還...
    沈念sama閱讀 46,598評論 2 362
  • 正文 我出身青樓蘸秘,卻偏偏與公主長得像,于是被迫代替她去往敵國和親蝗茁。 傳聞我的和親對象是個殘疾皇子醋虏,可洞房花燭夜當晚...
    茶點故事閱讀 43,697評論 2 351

推薦閱讀更多精彩內容