歡迎你們前往騰訊雲+社區,獲取更多騰訊海量技術實踐乾貨哦~javascript
本文由 騰訊雲視頻發表於 雲+社區專欄
關注公衆號「騰訊雲視頻」,一鍵獲取 技術乾貨 | 優惠活動 | 視頻方案java
本是一名佛性型吃雞選手,自從被三個妹子帶着躺屍吃雞以後,便立志要成爲一名吃雞高手,一大早便沉迷於各大網站的吃雞直播中,正看到決賽圈激動人心的時刻,直播花屏了?而後遊戲結束了?個人天,我是誰?我在哪?我錯過了什麼?安全
做爲一名有強迫症的IT小哥哥,怎能讓直播花屏現象存在呢?一方面,爲了本身能成爲一名吃雞高手。另外一方面,不能錯過每個升職加薪的機會。就這樣開始了一段漫長的長征之路……網絡
對於直播業務,"秒開、卡頓、時延、進房成功率"是咱們常常關注的幾個指標,這些指標能夠說是從"一個用戶可以優雅地進入直播間"的角度來考量的,然而進入直播間後"用戶究竟看到的什麼內容"也是很關鍵的一環,內容上除了涉及安全的一些指標外,還可能會有內容是否有花屏、綠屏等其餘異常內容,這時咱們便會考慮如何衡量和發現外網的花屏狀況。框架
本文主要針對花屏提出了一種基於CNN網絡的檢測方案。機器學習
01工具
花屏檢測能力構建 學習
不管是視頻仍是直播,都是由一幀幀圖像組成的,之因此會以一種動態的形式展示到咱們眼前,是由於了人類的視覺暫留現象。測試
物體在快速運動時, 當人眼所看到的影像消失後,人眼仍能繼續保留其影像0.1-0.4秒左右的圖像,這種現象被稱爲視覺暫留現象。網站
既然如此,檢測直播中是否存在花屏,其實能夠轉換爲檢測直播中的幀畫面是不是花屏的畫面,即一個圖像識別問題。那麼如何識別一個圖像是不是花屏呢?
一般圖像識別老是以特徵爲基礎的,咱們會先根據所設定的目標來提取相應的特徵,用於咱們後面來制定策略。不過好在如今的深度學習卷積神經網絡CNN將提取特徵和制定決策策略都幫咱們完成了。
而使用深度學習CNN網絡則繞不開數據集和模型訓練兩大塊
1.1數據集準備
困難
要使用深度學習網絡,一個門檻是須要足夠的帶有標籤的數據集,不然學習出的網絡很容易過擬合,從而泛化能力不強。說其是門檻是由於實際業務中更多狀況是缺乏數據集,就以如今的花屏爲例,目前直播發生花屏的案例很是少,想要經過實際案例來收集足夠的花屏圖片做爲訓練集顯得異常困難。所以必須探尋其餘的路子來收集訓練集。
人類之因此可以分辨出花屏,是由於人類眼睛可以找到花屏圖像的特徵,雖然這些特徵咱們可能用語言都描述不出來,事實上,若是咱們能用語言描述出特徵,咱們也很容易將其翻譯成代碼來找到花屏圖像的特徵。
製做訓練集
機器學習其實也是經過特徵來工做的,既然如此,咱們能夠製做一些花屏圖像出來,讓CNN網絡找到它們區別於正常圖片的特徵,從而學習到花屏圖片的檢測能力。
在使用YUVviewer工具時,發現當設置錯誤的分辨率來播放視頻文件時會出現花屏狀況。靈感來源於此,咱們徹底能夠經過使用錯誤的分辨率從YUV文件中抽取幀,從而拿到花屏圖片。總體流程以下:
這裏須要瞭解YUV文件的存儲格式,從而根據格式來進行抽取對應的幀:
YUV,分爲三個份量,「Y」表示明亮度(Luminance或Luma),也就是灰度值;而「U」和「V」 表示的則是色度(Chrominance或Chroma),做用是描述影像色彩及飽和度,用於指定像素的顏色。
YUV採樣樣式有一下幾種,以黑點表示採樣該像素點的Y份量,以空心圓圈表示採用該像素點的UV份量,通常狀況下咱們都使用的是YUV420格式
YUV420格式存儲方式以下所示:
按照上面存儲方式編寫代碼來提取幀,代碼以下:
def get_frames_from_YUV(filename, dims, numfrm, startfrm, frmstep): """ 從給定的YUV文件中抽取對應的幀數據,幀數據格式仍然爲YUV :param filename: YUV文件路徑 :param dims: YUV文件的分辨率 :param numfrm: 要提取幀的數量 :param startfrm: 從哪一幀開始提取 :param frmstep: 抽取幀的幀間隔,即每隔幾幀抽一幀 :return: 返回抽取幀的Y列表,U列表,V列表 """ filesize = os.path.getsize(filename) fp = open(filename, 'rb') blk_size = prod(dims) * 3 / 2 # 計算每幀大小 if (startfrm+1+(numfrm-1)*frmstep)*blk_size > filesize: numfrm = (filesize/blk_size - 1 - startfrm)/frmstep +1 util.log('文件讀取越界--修改成%d'%numfrm) fp.seek(blk_size * startfrm, 0) # 跳轉到指定開始幀 Y, U, V= [],[],[] d00 = dims[0] / 2 d01 = dims[1] / 2 for i in range(numfrm): util.log('文件讀取第%d幀' % i) Yt = zeros((dims[1], dims[0]), uint8, 'C') Ut = zeros((d01, d00), uint8, 'C') Vt = zeros((d01, d00), uint8, 'C') for m in range(dims[1]): for n in range(dims[0]): # print m,n Yt[m, n] = ord(fp.read(1)) for m in range(d01): for n in range(d00): Ut[m, n] = ord(fp.read(1)) for m in range(d01): for n in range(d00): Vt[m, n] = ord(fp.read(1)) Y = Y + [Yt] U = U + [Ut] V = V + [Vt] fp.seek(blk_size * (frmstep - 1), 1) # 跳出間隔幀 fp.close() return (Y, U, V)
這裏對分辨率錯誤的多種狀況也作了下研究,發現以下規律:
1)分辨率正確
2)分辨率width+1狀況
3)分辨率width+n狀況
4)分辨率width-1狀況
5)分辨率width-n狀況
上面只是針對圖片寬來進行錯誤干擾,能夠看出寬變小花屏條紋方向是左下的,寬變大花屏條紋方向時右下的。
因此咱們隊寬和高分別設置不一樣的錯誤值,會形成不一樣類型的花屏,因而能夠用這種策略構造大量的花屏。
咱們用800多個視頻,每一個視頻以必定的間隔來抽10幀,得到了8000多張花屏圖片。
這些圖片標籤爲花屏,也就是咱們的正樣本,負樣本可選取實際直播中的正常截圖。
至此,數據集準備差很少了。
1.2 模型和訓練
模型上使用網上一些知名模型便可,這裏咱們使用了輕量的mobilenet模型,模型結構以下圖所示:
訓練採用基於用imagenet已經訓練好的模型來進行finetune訓練,最後一層使用隨機超參數來訓練(這一層也沒法讀取pretrained模型的超參數,由於分類數不一致)。訓練能夠快速收斂,由於特徵太明顯了,並且測試集準確率很高。
其實這裏訓練是一個不斷迭代的過程,由於機器學習模型是一張白紙,它要具備怎樣的能力徹底是你教它的,而教的方式就是經過訓練集(數據和標籤),而想要讓它可以應對更多的狀況,你的訓練集就要儘量涵蓋各類狀況。
而咱們的訓練集老是不足的,你總會有care不到的地方。訓練集不足的狀況會怎樣?舉個例子
你訓練個識別飛機的模型,而大部分關於飛機的圖片都有天空,這樣你給張天空的圖片到模型,它也可能會認爲是飛機,由於其實模型極可能學到的是天空的特徵。而怎麼讓模型學到飛機的特徵呢,固然須要調整訓練集,讓訓練集裏不只包含背景爲天空的飛機,還有陸地上的飛機等等。
經過不斷低迭代調優,咱們在空間場景下檢測準確率已經能夠達到94%,NOW直播場景檢測準確率也已達到90%。
02
直播檢測方案
檢測能力具有後想要真正地接入直播業務,還須要將直播流進行分幀,而後把對應的幀圖片進行花屏檢測。
後臺總體框架
採用分幀截屏的手段,若是天天須要檢測2000萬張截圖,即10s會有一張截圖須要檢測,而考慮花屏老是出如今很長的一段時間內,所以這裏但願可以以更長的時間來抽樣從而避免浪費算力。
附一張目前業務檢測花屏結果的截圖:
做爲一名熱愛工做的IT小哥哥,花了一個星期的時間,總算把基於CNN網絡的直播花屏檢測的工做告一段落了。
工做使我開心,遊戲使我快樂,終於能夠再次流暢的遊走在各大網址的吃雞直播中啦~
問答
遊戲體系結構
相關閱讀
團戰開黑必備「良藥」瞭解一下!
不再用擔憂網吧開黑隊友聽不清了!
3行代碼,爲QQ輕遊戲加上語音互動能力
【每日課程推薦】機器學習實戰!快速入門在線廣告業務及CTR相應知識
此文已由做者受權騰訊雲+社區發佈,更多原文請點擊
搜索關注公衆號「雲加社區」,第一時間獲取技術乾貨,關注後回覆1024 送你一份技術課程大禮包!
海量技術實踐經驗,盡在雲加社區!