1. 程式人生 > >使用TensorFlow進行訓練識別視訊影象中物體

使用TensorFlow進行訓練識別視訊影象中物體

640?wx_fmt=png

本教程針對Windows10實現谷歌公佈的TensorFlow Object Detection API視訊物體識別系統,其他平臺也可借鑑。

本教程將網路上相關資料篩選整合(文末附上參考資料連結),旨在為快速搭建環境以及實現視訊物體識別功能提供參考,關於此API的更多相關資訊請自行搜尋。

注意: windows使用者名稱不能出現中文!!!

安裝Python

注意: Windows平臺的TensorFlow僅支援3.5.X版本的Python
進入Python3.5.2下載頁,選擇 Files 中Windows平臺的Python安裝包,下載並安裝。

640?wx_fmt=png

安裝TensorFlow

進入TensorFlow on Windows下載頁,本教程使用最簡便的組合 CPU support only + Native pip。

開啟cmd,輸入以下指令即進行TensorFlow的下載安裝,下載位置為python\Lib\site-packages\tensorflow:

640?wx_fmt=png

開啟 IDLE,輸入以下指令:

640?wx_fmt=png

如果出現如下結果則安裝成功:

640?wx_fmt=png

若出現問題,請參考TensorFlow on Windows下載頁底端的常見問題。

640?wx_fmt=png

安裝Protoc

Protoc用於編譯相關程式執行檔案,進入Protoc下載頁,下載類似下圖中帶win32的壓縮包。

640?wx_fmt=png

解壓後將bin資料夾內的protoc.exe拷貝到c:\windows\system32目錄下(用於將protoc.exe所在的目錄配置到環境變數當中)。

安裝git

進入git官網下載Windows平臺的git,詳細安裝及配置注意事項可參考此文。

640?wx_fmt=png

安裝其餘元件

在cmd內輸入如下指令下載並安裝相關API執行支援元件:

640?wx_fmt=png

注意: Native pip會受電腦中另外Python應用的影響,博主因為之前做模擬安裝了Anaconda,導致下載的jupyter等相關元件安裝到了Anaconda內的site-packages資料夾,後期呼叫失敗。

下載程式碼並編譯

在cmd中輸入如下程式碼:

640?wx_fmt=png

從github下載谷歌tensorflow/models的程式碼,一般預設下載到C盤。

同樣在cmd進入到models資料夾,編譯Object Detection API的程式碼:

640?wx_fmt=png

執行notebook demo

繼續在models資料夾下執行如下命令:

640?wx_fmt=png

瀏覽器自動開啟,顯示如下介面:

640?wx_fmt=png

進入object_detection資料夾中的object_detection_tutorial.ipynb:

640?wx_fmt=png

點選Cell內的Run All,等待三分鐘左右(博主電腦接近報廢),即可顯示如下結果:

640?wx_fmt=png

640?wx_fmt=png

修改檔案路徑,即可檢測自己的圖片:

640?wx_fmt=png

640?wx_fmt=png

640?wx_fmt=png

注意:要將圖片名稱設定的和程式碼描述相符合,如image1.jpg

640?wx_fmt=png

TensorFlow Object Detection API中提供了五種可直接呼叫的識別模型,預設的是最簡單的ssd + mobilenet模型。

640?wx_fmt=png

640?wx_fmt=png

可直接將MODEL_NAME修改為如下值呼叫其他模型:

MODEL_NAME = 'ssd_inception_v2_coco_11_06_2017'

MODEL_NAME = 'rfcn_resnet101_coco_11_06_2017'

MODEL_NAME = 'faster_rcnn_resnet101_coco_11_06_2017'

MODEL_NAME = 'faster_rcnn_inception_resnet_v2_atrous_coco_11_06_2017'

將模型換為faster_rcnn_inception_resnet,結果如下:

640?wx_fmt=png

640?wx_fmt=png

準確率確實獲得了極大提高,但是速度卻下降了,在博主的老爺機上需要五分鐘才能跑出結果。

視訊物體識別

谷歌在github上公佈了此專案的完整程式碼,接下來我們將在現有程式碼基礎上新增相應模組實現對於視訊中物體的識別。

第一步:下載opencv的cv2包

640?wx_fmt=png

在Python官網即可下載opencv相關庫,點選此處直接進入。

博主安裝的版本如下:

640?wx_fmt=png

下載完成後,在cmd中執行安裝命令

pip install opencv_python-3.2.0.8-cp35-cp35m-win_amd64.whl

安裝完成後,進入IDLE輸入命令

import cv2

若未報錯,則opencv-python庫成功匯入,環境搭配成功。

第二步:在原始碼中引入cv2包

640?wx_fmt=png

第三步:新增視訊識別程式碼
主要步驟如下:
1.使用 VideoFileClip 函式從視訊中抓取圖片。
2.用fl_image函式將原圖片替換為修改後的圖片,用於傳遞物體識別的每張抓取圖片。
3.所有修改的剪輯影象被組合成為一個新的視訊。

在原版程式碼基礎上,在最後面依次新增如下程式碼(可從完整程式碼 處複製,但需要作出一些改變,當然也可以直接從下文複製修改後的程式碼):

640?wx_fmt=png

# Import everything needed to edit/save/watch video clips
import imageio
imageio.plugins.ffmpeg.download()

from moviepy.editor import VideoFileClip
from IPython.display import HTML

此處會下載一個剪輯必備的程式ffmpeg.win32.exe,內網下載過程中容易斷線,可以使用下載工具下載完然後放入如下路徑:

C:\Users\ 使用者名稱 \AppData\Local\imageio\ffmpeg\ffmpeg.win32.exe

def detect_objects(image_np, sess, detection_graph):
    # Expand dimensions since the model expects images to have shape: [1, None, None, 3]
    image_np_expanded = np.expand_dims(image_np, axis=0)
    image_tensor = detection_graph.get_tensor_by_name('image_tensor:0')

    # Each box represents a part of the image where a particular object was detected.
    boxes = detection_graph.get_tensor_by_name('detection_boxes:0')

    # Each score represent how level of confidence for each of the objects.
    # Score is shown on the result image, together with the class label.
    scores = detection_graph.get_tensor_by_name('detection_scores:0')
    classes = detection_graph.get_tensor_by_name('detection_classes:0')
    num_detections = detection_graph.get_tensor_by_name('num_detections:0')

    # Actual detection.
    (boxes, scores, classes, num_detections) = sess.run(
        [boxes, scores, classes, num_detections],
        feed_dict={image_tensor: image_np_expanded})

    # Visualization of the results of a detection.
    vis_util.visualize_boxes_and_labels_on_image_array(
        image_np,
        np.squeeze(boxes),
        np.squeeze(classes).astype(np.int32),
        np.squeeze(scores),
        category_index,
        use_normalized_coordinates=True,
        line_thickness=8)
    return image_np

處理影象

def process_image(image):
    NOTE: The output you return should be a color image (3 channel) for processing video below
    # you should return the final output (image with lines are drawn on lanes)
    with detection_graph.as_default():
        with tf.Session(graph=detection_graph) as sess:
            image_process = detect_objects(image, sess, detection_graph)
            return image_process

輸入視訊檔案

white_output = 'video1_out.mp4'
clip1 = VideoFileClip("video1.mp4").subclip(25,30)
white_clip = clip1.fl_image(process_image) #NOTE: this function expects color images!!s
%time white_clip.write_videofile(white_output, audio=False)

其中video1.mp4已經從電腦中上傳至object_detection資料夾,subclip(25,30)代表識別視訊中25-30s這一時間段。

原版視訊:

640?wx_fmt=gif

展示識別完畢的視訊:

640?wx_fmt=gif

from moviepy.editor import *
clip1 = VideoFileClip("video1_out.mp4")
clip1.write_gif("final.gif")

將識別完畢的視訊導為gif格式,並儲存至object_detection資料夾。

至此,快速教程結束。各位應該都能使用谷歌開放的API實現了視訊物體識別。

相關參考資料

  • 知乎:何之源對於“谷歌開放的TensorFlow Object Detection API 效果如何?”的回答

  • 林俊宇的部落格:匯入opencv-python庫

  • myboyliu2007的專欄:ffmpeg安裝方法

  • 陳強:安裝protocolbuffer詳解

  • 機器之心:如何使用TensorFlow API構建視訊物體識別系統

  • windows安裝git和環境變數配置

原創作者:withzheng,原文連結:https://blog.csdn.net/xiaoxiao123jun/article/details/76605928
Demo原始碼下載點選閱讀原文

640?wx_fmt=png