1. 程式人生 > >通過圖像識別監控屏幕畫面卡死問題

通過圖像識別監控屏幕畫面卡死問題

odi license Coding 0.12 一個人 png rate 圖像 ctu

一、背景需求

公司視頻組最近在錄制某款遊戲的PVP視頻,視頻錄制好以後再上傳到後端存儲。但是在錄制的過程中,有可能錄制視頻程序會有視頻卡死不動的情況,即:錄制程序在運行,但是後臺渲染引擎工作異常,也就是遊戲畫面不變,但是視頻程序還是在錄制視頻中。比如下面2張圖片(暫且將新聞頁面當做正在錄制的視頻,不同點我已標出):

技術分享圖片

技術分享圖片

二、需求分析

縱觀整個過程,首先想嘗試進行如下分析:

  1、從數據層面,抓取數據包異常特征,比如在渲染引擎工作異常時,數據包或者網絡流量的大小是否會突升或突降?

  2、從系統層面,監控錄制程序的資源占用情況(CPU/內存/IO),錄制畫面卡住時,錄制程序占用資源是否有異常?

  3、從代碼層面,需要開發視頻錄制程序的程序員進行相關日誌輸出,然後看是否可以看到錯誤日誌?

針對情況1,從數據層面看,渲染引擎工作異常,但是錄制程序還是照常錄制,只是錄制的畫面一直是出現異常時這一刻的屏幕畫面,所以數據包不會有變化;

針對情況2,系統層面,針對錄制程序進行了專門的監控,但是後臺引擎異常時,錄制進行資源基本不會變化,所以這一個嘗試也失敗了;

針對情況3,代碼層面,錄制程序確實有錯誤日誌產生,針對這個情況,開發人員進行了重連渲染引擎的方法,雖然通過這種方法已經基本上解決了問題,但是還是有一部分概率即使在重啟渲染引擎進程後,錄制的遊戲畫面還是不變,即一直錄制的同一個畫面。這時,需要開發人員對整套錄制程序進行重啟才能徹底解決。

以上只是交代了監控背景:視頻組負責人要求運維這邊針對出現一直是同一個畫面的情況進行監控,如果有這種情況,及時通知他們,進行線上解決,當然,這也只是臨時方法,後期還是要他們程序支持自動檢測的,不然,這麽老土的辦法就算是開發自己,我想也會感到心裏不安的。(半夜裏電話吵醒來重啟進程)

三、解決方案

針對畫面不動進行監控,我在網上找了一些方法,但是都不能真正解決,比如:使用按鍵精靈,截取屏幕後通過圖片大小進行對比;或者幹脆使用截屏軟件進行屏幕截取,然後比較文件的md5等等之類的,雖然圖片能夠截取,但是問題都不能解決,對比下來結果相差甚遠。

腦子裏一直想著圖片處理、圖片處理。。。。。突然,靈光一閃,最近不是機器學習、圖片識別不是很火麽?既然能夠截取屏幕,我們通過截屏的圖片進行識別不就可以了麽?解決方法找到了,就開始找方案。

四、OpenCV

1、OpeCV介紹

OpenCV (Open Source Computer Vision Library) is an open source computer vision and machine learning software library. OpenCV was built to provide a common infrastructure for computer vision applications and to accelerate the use of machine perception in the commercial products. Being a BSD-licensed product, OpenCV makes it easy for businesses to utilize and modify the code.

OpenCV--開源可視化計算庫。它是一個開源計算可視化和機器學習的庫。

2、OpenCV怎麽識別兩張照片呢?

比如怎麽從一張大圖和一張小圖裏面識別同一個圖像呢?從機器的角度來說是這樣的,先識別圖像的特征,然後再相比,通過相似度進行判斷是否為同一個人。

實現代碼如下:

#!/usr/bin/env python
# coding:utf-8
from PIL import ImageGrab
import time
import os
import cv2
import numpy as np
from matplotlib import pyplot as plt

# 抓取當前屏幕
cur_dir = os.path.dirname(__file__)
im = ImageGrab.grab()
im.save(os.path.join(cur_dir,"%s.png" %time.time()))

# 獲取當前目錄下所有png文件
def all_path(dirname):
    result = []
    for maindir, subdir, file_name_list in os.walk(dirname):
        for filename in file_name_list:
            if filename.endswith(.png):
                apath = os.path.join(maindir, filename)
                result.append(apath)
    return result

# 獲取最新的兩個文件
def get_max_two(file_list):
    rt = []
    for f in file_list:
        rt.append((f,os.path.getctime(f)))
    rt = sorted(rt,key=lambda x:x[1],reverse=True)
    return rt[0][0],rt[1][0]


# 計算單通道的直方圖的相似值
def calculate(image1, image2):
    hist1 = cv2.calcHist([image1], [0], None, [256], [0.0, 255.0])
    hist2 = cv2.calcHist([image2], [0], None, [256], [0.0, 255.0])
    # 計算直方圖的重合度
    degree = 0
    for i in range(len(hist1)):
        if hist1[i] != hist2[i]:
            degree = degree + (1 - abs(hist1[i] - hist2[i]) / max(hist1[i], hist2[i]))
        else:
            degree = degree + 1
    degree = degree / len(hist1)
    return degree


# 通過得到每個通道的直方圖來計算相似度
def classify_hist_with_split(image1, image2, size=(256, 256)):
    # 將圖像resize後,分離為三個通道,再計算每個通道的相似值
    image1 = cv2.resize(image1, size)
    image2 = cv2.resize(image2, size)
    sub_image1 = cv2.split(image1)
    sub_image2 = cv2.split(image2)
    sub_data = 0
    for im1, im2 in zip(sub_image1, sub_image2):
        sub_data += calculate(im1, im2)
    sub_data = sub_data / 3
    return sub_data


if __name__ == __main__:
    # 獲取2張圖片的相似度
    cur_dir = os.path.dirname(__file__)
    file_list = all_path(cur_dir)
    img1, img2 = get_max_two(file_list)
    # print img1,img2

    img1 = cv2.imread(img1)
    # cv2.imshow(‘img1‘, img1)
    img2 = cv2.imread(img2)
    # cv2.imshow(‘img2‘, img2)
    degree =  classify_hist_with_split(img1, img2)
    if isinstance(degree, int):
        with open(os.path.join(cur_dir, "a.txt"), w+) as f:
            f.write(str(degree))
    else:
        with open(os.path.join(cur_dir,"a.txt"),w+) as f:
            f.write(str(degree[0]))

解釋一下以上腳本的整個過程:

1、抓取當前屏幕,並以時間為文件名進行保存;

2、取出當前最新的2張圖片;

3、獲取當前2張照片的相似度,並寫入文件a.txt;

4、通過從a.txt讀取相似度進行監控,相似度達到某個值,比如99%以上就判斷為屏幕卡死了。

五、實現

1、設置計劃任務

把上面寫好的腳本放入系統的計劃任務中運行:

技術分享圖片

技術分享圖片

技術分享圖片

結果如下:

技術分享圖片

文件記錄的相似度值:

技術分享圖片

2、通過zabbix進行監控

自定義監控項

UserParameter=get_degree,type d:\pych\a.txt

獲取監控值

[root@localhost ~]# zabbix_get -s 10.20.122.18 -kget_degree

0.996

設置觸發器

技術分享圖片

通過圖像識別監控屏幕畫面卡死問題