複雜環境下的視頻流識別—茫茫大海中一眼看到你 | 解讀技術

更多AI資訊,關註:九三智能控

視頻流識別與抓拍圖片進行識別存在區別,通過視頻流識別可實現對攝像頭採集到的所有圖片進行快速分析,按照設定存儲規則存儲所需的圖片。隨著視頻攝像頭的高清化以及應用場景的海量增長,對監控系統視頻信號的存儲帶來巨大的挑戰,存儲空間永遠都是不夠用的,同時對視頻信號的利用也帶來很大困難,導致大量視頻信號存而不用。

隨著深度學習等人工智慧技術快速發展,通過視頻流實時分析視頻信號,實時選擇需要存在的有效視頻信號得到快速發展,避免了大量低價值視頻信號的存儲問題,同時有利於視頻信號的高效利用。特別是,在人臉識別領域已經得到規模化應用,能夠通過各種鋪設的攝像頭識別人群中的多人身份,實現快速定位特定人員、信息匹配的目的。例如公安在處理刑偵案件時最大的痛點,是遇到警情或案件時,需要對20多小時的視頻資料逐幀排查。不僅效率低下,還容易錯過關鍵信息。因此公安希望能夠通過AI的加持,在特定時間特定區域下對可疑人群做快速識別。公安只需要輸入嫌疑人照片,設定時間、地點便能夠實現快速識別與定位。目前,實現高效、智能化、自動化的人臉識別、數據處理和分析,已成為大勢所趨。

  • 對於不具備機器視覺能力的攝像頭可以通過人工智慧SDK與雲端後台管理系統進行連接,獲取演算法支持,實現對於視頻流實時處理。
  • 對於具備機器視覺能力的攝像頭通過內置視頻流智能演算法程序實現特定目標的識別,依賴本地硬體資源實現有限目標的識別。

未來人臉識別等智能演算法的壁壘將會逐漸消除,越來越多的公司會將注意力放在視頻流識別的實際場景的應用中,實際場景的痛點挖掘及細分將成為重點發力領域。隨著人臉識別等智能演算法模型的日漸成熟,市場容量飽和速度越來越快,已經完成原始積累和市場開拓的公司將會牢牢把持人臉市場,後續公司進入難度越來越大,生存空間持續被擠壓。而在工業領域的特定視頻流識別會成為新興發展市場,這需要工業領域知識又需要視頻流識別智能演算法模型的知識,比如鐵軌是否有裂縫等民生場景,通過機器識別的應用將能大大提升工作效率。

程序實例:

1獲取視頻流

利用OpenCV獲取USB攝像頭的視頻流的程序如下:

#-*- coding: utf-8 -*-

import cv2

import sys

from PIL import Image

def CatchUsbVideo(window_name, camera_idx):

cv2.namedWindow(window_name)

#視頻來源,可以來自一段已存好的視頻,也可以直接來自USB攝像頭

cap = cv2.VideoCapture(camera_idx)

while cap.isOpened():

ok, frame = cap.read() #讀取一幀數據

if not ok:

break

#顯示圖像並等待10毫秒按鍵輸入,輸入『q』退出程序

cv2.imshow(window_name, frame)

c = cv2.waitKey(10)

if c & 0xFF == ord(q):

break

#釋放攝像頭並銷毀所有窗口

cap.release()

cv2.destroyAllWindows()

__main__:

if len(sys.argv) != 2:

print("Usage:%s camera_id " % (sys.argv[0]))

else:

CatchUsbVideo("截取視頻流", int(sys.argv[1]))

2 識別人臉程序

#-*- coding: utf-8 -*-

import cv2

import sys

from PIL import Image

def CatchUsbVideo(window_name, camera_idx):

cv2.namedWindow(window_name)

#視頻來源,可以來自一段已存好的視頻,也可以直接來自USB攝像頭

cap = cv2.VideoCapture(camera_idx)

#告訴OpenCV使用人臉識別分類器

classfier = cv2.CascadeClassifier("/usr/local/share/OpenCV/haarcascades/haarcascade_frontalface_alt2.xml")

#識別出人臉後要畫的邊框的顏色,RGB格式

color = (0, 255, 0)

while cap.isOpened():

ok, frame = cap.read() #讀取一幀數據

if not ok:

break

#將當前幀轉換成灰度圖像

grey = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)

#人臉檢測,1.2和2分別為圖片縮放比例和需要檢測的有效點數

faceRects = classfier.detectMultiScale(grey, scaleFactor = 1.2, minNeighbors = 3, minSize = (32, 32))

if len(faceRects) > 0: #大於0則檢測到人臉

for faceRect in faceRects: #單獨框出每一張人臉

x, y, w, h = faceRect

cv2.rectangle(frame, (x - 10, y - 10), (x + w + 10, y + h + 10), color, 2)

#顯示圖像

cv2.imshow(window_name, frame)

c = cv2.waitKey(10)

if c & 0xFF == ord(q):

break

#釋放攝像頭並銷毀所有窗口

cap.release()

cv2.destroyAllWindows()

if __name__ == __main__:

if len(sys.argv) != 2:

print("Usage:%s camera_id " % (sys.argv[0]))

else:

CatchUsbVideo("識別人臉區域", int(sys.argv[1]))

3為人臉識別準備數據

#-*- coding: utf-8 -*-

import cv2

import sys

from PIL import Image

def CatchPICFromVideo(window_name, camera_idx, catch_pic_num, path_name):

cv2.namedWindow(window_name)

#視頻來源,可以來自一段已存好的視頻,也可以直接來自USB攝像頭

cap = cv2.VideoCapture(camera_idx)

#告訴OpenCV使用人臉識別分類器

classfier = cv2.CascadeClassifier("/usr/local/share/OpenCV/haarcascades/haarcascade_frontalface_alt2.xml")

#識別出人臉後要畫的邊框的顏色,RGB格式

color = (0, 255, 0)

num = 0

while cap.isOpened():

ok, frame = cap.read() #讀取一幀數據

if not ok:

break

grey = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY) #將當前楨圖像轉換成灰度圖像

#人臉檢測,1.2和2分別為圖片縮放比例和需要檢測的有效點數

faceRects = classfier.detectMultiScale(grey, scaleFactor = 1.2, minNeighbors = 3, minSize = (32, 32))

if len(faceRects) > 0: #大於0則檢測到人臉

for faceRect in faceRects: #單獨框出每一張人臉

x, y, w, h = faceRect

#將當前幀保存為圖片

img_name = %s/%d.jpg%(path_name, num)

image = frame[y - 10: y + h + 10, x - 10: x + w + 10]

cv2.imwrite(img_name, image)

num += 1

if num > (catch_pic_num): #如果超過指定最大保存數量退出循環

break

#畫出矩形框

cv2.rectangle(frame, (x - 10, y - 10), (x + w + 10, y + h + 10), color, 2)

#顯示當前捕捉到了多少人臉圖片了,這樣站在那裡被拍攝時心裡有個數,不用兩眼一抹黑傻等著

font = cv2.FONT_HERSHEY_SIMPLEX

cv2.putText(frame,num:%d % (num),(x + 30, y + 30), font, 1, (255,0,255),4)

#超過指定最大保存數量結束程序

if num > (catch_pic_num): break

#顯示圖像

cv2.imshow(window_name, frame)

c = cv2.waitKey(10)

if c & 0xFF == ord(q):

break

#釋放攝像頭並銷毀所有窗口

cap.release()

cv2.destroyAllWindows()

if __name__ == __main__:

if len(sys.argv) != 4:

print("Usage:%s camera_id face_num_max path_name " % (sys.argv[0]))

else:

CatchPICFromVideo("截取人臉", int(sys.argv[1]), int(sys.argv[2]), sys.argv[3])

4利用Keras訓練人臉識別模型

# -*- coding: utf-8 -*-

import os

import sys

import numpy as np

import cv2

IMAGE_SIZE = 64

#按照指定圖像大小調整尺寸

def resize_image(image, height = IMAGE_SIZE, width = IMAGE_SIZE):

top, bottom, left, right = (0, 0, 0, 0)

#獲取圖像尺寸

h, w, _ = image.shape

#對於長寬不相等的圖片,找到最長的一邊

longest_edge = max(h, w)

#計算短邊需要增加多上像素寬度使其與長邊等長

if h < longest_edge:

dh = longest_edge - h

top = dh // 2

bottom = dh - top

elif w < longest_edge:

dw = longest_edge - w

left = dw // 2

right = dw - left

else:

pass

#RGB顏色

BLACK = [0, 0, 0]

#給圖像增加邊界,是圖片長、寬等長,cv2.BORDER_CONSTANT指定邊界顏色由value指定

constant = cv2.copyMakeBorder(image, top , bottom, left, right, cv2.BORDER_CONSTANT, value = BLACK)

#調整圖像大小並返回

return cv2.resize(constant, (height, width))

#讀取訓練數據

images = []

labels = []

def read_path(path_name):

for dir_item in os.listdir(path_name):

#從初始路徑開始疊加,合併成可識別的操作路徑

full_path = os.path.abspath(os.path.join(path_name, dir_item))

if os.path.isdir(full_path): #如果是文件夾,繼續遞歸調用

read_path(full_path)

else: #文件

if dir_item.endswith(.jpg):

image = cv2.imread(full_path)

image = resize_image(image, IMAGE_SIZE, IMAGE_SIZE)

#放開這個代碼,可以看到resize_image()函數的實際調用效果

#cv2.imwrite(1.jpg, image)

images.append(image)

labels.append(path_name)

return images,labels

#從指定路徑讀取訓練數據

def load_dataset(path_name):

images,labels = read_path(path_name)

#將輸入的所有圖片轉成四維數組,尺寸為(圖片數量*IMAGE_SIZE*IMAGE_SIZE*3)

#我和閨女兩個人共1200張圖片,IMAGE_SIZE為64,故對我來說尺寸為1200 * 64 * 64 * 3

#圖片為64 * 64像素,一個像素3個顏色值(RGB)

images = np.array(images)

print(images.shape)

#標註數據,me文件夾下都是我的臉部圖像,全部指定為0,另外一個文件夾下是閨女的,全部指定為1

labels = np.array([0 if label.endswith(me) else 1 for label in labels])

return images, labels

if __name__ == __main__:

if len(sys.argv) != 2:

print("Usage:%s path_name " % (sys.argv[0]))

else:

images, labels = load_dataset(sys.argv[1])

5視頻流識別特定目標

#識別人臉

def face_predict(self, image):

#依然是根據後端系統確定維度順序

if K.image_dim_ordering() == th and image.shape != (1, 3, IMAGE_SIZE, IMAGE_SIZE):

image = resize_image(image) #尺寸必須與訓練集一致都應該是IMAGE_SIZE x IMAGE_SIZE

image = image.reshape((1, 3, IMAGE_SIZE, IMAGE_SIZE)) #與模型訓練不同,這次只是針對1張圖片進行預測

elif K.image_dim_ordering() == tf and image.shape != (1, IMAGE_SIZE, IMAGE_SIZE, 3):

image = resize_image(image)

image = image.reshape((1, IMAGE_SIZE, IMAGE_SIZE, 3))

#浮點並歸一化

image = image.astype(float32)

image /= 255

#給出輸入屬於各個類別的概率,我們是二值類別,則該函數會給出輸入圖像屬於0和1的概率各為多少

result = self.model.predict_proba(image)

print(result:, result)

#給出類別預測:0或者1

result = self.model.predict_classes(image)

#返回類別預測結果

return result[0]

#-*- coding: utf-8 -*-

import cv2

import sys

import gc

from face_train_use_keras import Model

if __name__ == __main__:

if len(sys.argv) != 2:

print("Usage:%s camera_id " % (sys.argv[0]))

sys.exit(0)

#載入模型

model = Model()

model.load_model(file_path = ./model/me.face.model.h5)

#框住人臉的矩形邊框顏色

color = (0, 255, 0)

#捕獲指定攝像頭的實時視頻流

cap = cv2.VideoCapture(int(sys.argv[1]))

#人臉識別分類器本地存儲路徑

cascade_path = "/usr/local/share/OpenCV/haarcascades/haarcascade_frontalface_alt2.xml"

#循環檢測識別人臉

while True:

_, frame = cap.read() #讀取一幀視頻

#圖像灰化,降低計算複雜度

frame_gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)

#使用人臉識別分類器,讀入分類器

cascade = cv2.CascadeClassifier(cascade_path)

#利用分類器識別出哪個區域為人臉

faceRects = cascade.detectMultiScale(frame_gray, scaleFactor = 1.2, minNeighbors = 3, minSize = (32, 32))

if len(faceRects) > 0:

for faceRect in faceRects:

x, y, w, h = faceRect

#截取臉部圖像提交給模型識別這是誰

image = frame[y - 10: y + h + 10, x - 10: x + w + 10]

faceID = model.face_predict(image)

#如果是「我」

if faceID == 0:

cv2.rectangle(frame, (x - 10, y - 10), (x + w + 10, y + h + 10), color, thickness = 2)

#文字提示是誰

cv2.putText(frame,Dady,

(x + 30, y + 30), #坐標

cv2.FONT_HERSHEY_SIMPLEX, #字體

1, #字型大小

(255,0,255), #顏色

2) #字的線寬

else:

pass

cv2.imshow("識別朕", frame)

#等待10毫秒看是否有按鍵輸入

k = cv2.waitKey(10)

#如果輸入q則退出循環

if k & 0xFF == ord(q):

break

#釋放攝像頭並銷毀所有窗口

cap.release()

cv2.destroyAllWindows()

參考資料:

cnblogs.com/neo-T/p/642

微信群&商業合作:

  • 加入微信群:不定期分享資料,拓展行業人脈請在公眾號留言:「微信號+名字+研究領域/專業/學校/公司」,我們將很快與您聯繫。
  • 投稿(無稿費)請發郵件至:158354995@qq.com

  • 商業合作請註明事宜哦

weixin.qq.com/r/AC91bd- (二維碼自動識別)


推薦閱讀:

語義分割&視頻分割開源代碼集合
【論文閱讀】Fully Convolutional Networks for Semantic Segmentation
第1期(1):計算機-圖像處理技巧(第1篇)

TAG:機器學習 | 計算機視覺 | 圖像分割 |