環(huán)境
首先安裝一下matplotlib庫:
sudo pip install matplotlib
下載1.4.1的tensorflow
https://github.com/lhelontra/tensorflow-on-arm/releases安裝
sudo pip uninstall tensorflow
sudo pip install --upgrade tensorflow-1.4.1-cp27-none-linux_armv7l.whl
準備模型
- 下載tensorflow提供的models API并解壓董朝,我這里解壓后的目錄為
models_master
,下載路徑:
https://github.com/tensorflow/models/tree/master/research/object_detection/models - 下載訓(xùn)練好的模型并放到上一步
models_master
下的object_detection/models
目錄罐柳,下載路徑:
https://github.com/tensorflow/models/blob/master/research/object_detection/g3doc/detection_model_zoo.md
這里下載幾個典型的:ssd_mobilenet_v1_coco_2017_11_17
洗鸵、faster_rcnn_resnet101_coco
和mask_rcnn_inception_v2_coco
注:做物體檢測的網(wǎng)絡(luò)有很多種恬惯,如faster rcnn浙宜,ssd,yolo等等蝶棋,通過不同維度的對比嵌赠,各個網(wǎng)絡(luò)都有各自的優(yōu)勢塑荒。
畢竟樹莓派計算能力有限,我們這里先選擇專門為速度優(yōu)化過最快的網(wǎng)絡(luò)SSD姜挺,以及經(jīng)典的faster-rcnn作對比齿税,再加上能顯示mask的高端網(wǎng)絡(luò),炊豪,凌箕,
事實上yolo v3剛出來,比SSD更快溜在,而faster rcnn相對來說運行慢的多了陌知,后面可以都嘗試對比一下,目前先把基線系統(tǒng)搭建好掖肋。
Protobuf 安裝與配置
- 說明
protobuf是Google開發(fā)的一種混合語言數(shù)據(jù)標(biāo)準仆葡,提供了一種輕便高效的結(jié)構(gòu)化數(shù)據(jù)存儲格式,可以用于結(jié)構(gòu)化數(shù)據(jù)序列化志笼。很適合做數(shù)據(jù)存儲或 RPC 數(shù)據(jù)交換格式沿盅。可用于通訊協(xié)議纫溃、數(shù)據(jù)存儲等領(lǐng)域的語言無關(guān)腰涧、平臺無關(guān)、可擴展的序列化結(jié)構(gòu)數(shù)據(jù)格式紊浩。目前提供了 C++窖铡、Java疗锐、Python 三種語言的 API。
下載地址:https://github.com/google/protobuf/releases
我們這里下載最新版本protobuf-all-3.5.1.tar.gz
- 安裝
tar -xf protobuf-all-3.5.1.tar.gz
cd protobuf-3.5.1
./configure
make
make check ->這一步是檢查編譯是否正確费彼,耗時非常長滑臊,可略過
sudo make install
sudo ldconfig ->更新庫搜索路徑,否則可能找不到庫文件
如果運行了make check
箍铲,結(jié)果如下雇卷,可以看到所有的測試用例都PASS了,說明編譯正確:
============================================================================
Testsuite summary for Protocol Buffers 3.5.1
============================================================================
# TOTAL: 7
# PASS: 7
# SKIP: 0
# XFAIL: 0
# FAIL: 0
# XPASS: 0
# ERROR: 0
============================================================================
- 配置
配置的目的是將proto格式的數(shù)據(jù)轉(zhuǎn)換為python格式颠猴,從而可以在python腳本中調(diào)用关划,進入目錄models-master/research
,運行:
protoc object_detection/protos/*.proto --python_out=.
轉(zhuǎn)換完畢后可以看到在object_detection/protos/
目錄下多了許多*.py文件翘瓮。
代碼
這里的代碼很簡單贮折,因為基本實現(xiàn)都已經(jīng)有了,我們只是調(diào)用一下接口實現(xiàn)功能即可资盅。
import numpy as np
import os
import sys
import tarfile
import tensorflow as tf
import cv2
import time
from collections import defaultdict
# This is needed since the notebook is stored in the object_detection folder.
sys.path.append("../..")
from object_detection.utils import label_map_util
from object_detection.utils import visualization_utils as vis_util
# What model to download.
MODEL_NAME = 'ssd_mobilenet_v1_coco_2017_11_17'
#MODEL_NAME = 'faster_rcnn_resnet101_coco_11_06_2017'
#MODEL_NAME = 'ssd_inception_v2_coco_11_06_2017'
MODEL_FILE = MODEL_NAME + '.tar.gz'
# Path to frozen detection graph. This is the actual model that is used for the object detection.
PATH_TO_CKPT = MODEL_NAME + '/frozen_inference_graph.pb'
# List of the strings that is used to add correct label for each box.
PATH_TO_LABELS = os.path.join('/home/yinan/object_detect/models-master/research/object_detection/data', 'mscoco_label_map.pbtxt')
#extract the ssd_mobilenet
start = time.clock()
NUM_CLASSES = 90
#opener = urllib.request.URLopener()
#opener.retrieve(DOWNLOAD_BASE + MODEL_FILE, MODEL_FILE)
tar_file = tarfile.open(MODEL_FILE)
for file in tar_file.getmembers():
file_name = os.path.basename(file.name)
if 'frozen_inference_graph.pb' in file_name:
tar_file.extract(file, os.getcwd())
end= time.clock()
print('load the model',(end-start))
detection_graph = tf.Graph()
with detection_graph.as_default():
od_graph_def = tf.GraphDef()
with tf.gfile.GFile(PATH_TO_CKPT, 'rb') as fid:
serialized_graph = fid.read()
od_graph_def.ParseFromString(serialized_graph)
tf.import_graph_def(od_graph_def, name='')
label_map = label_map_util.load_labelmap(PATH_TO_LABELS)
categories = label_map_util.convert_label_map_to_categories(label_map, max_num_classes=NUM_CLASSES, use_display_name=True)
category_index = label_map_util.create_category_index(categories)
cap = cv2.VideoCapture(0)
with detection_graph.as_default():
with tf.Session(graph=detection_graph) as sess:
writer = tf.summary.FileWriter("logs/", sess.graph)
sess.run(tf.global_variables_initializer())
while(1):
start = time.clock()
ret, frame = cap.read()
if cv2.waitKey(1) & 0xFF == ord('q'):
break
image_np=frame
# the array based representation of the image will be used later in order to prepare the
# result image with boxes and labels on it.
# 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=6)
end = time.clock()
#print('frame:',1.0/(end - start))
print 'One frame detect take time:',end - start
cv2.imshow("capture", image_np)
print('after cv2 show')
cv2.waitKey(1)
cap.release()
cv2.destroyAllWindows()
保存為 detect.py
脱货,到目錄models-master/research/object_detection/models
下。
運行
命令:
sudo chmod 666 /dev/video0
python detect.py
效果
SSD模型
下圖可以看到律姨,SSD模型加載模型花了8s,差不多一張圖識別時間在5s:
PS. 為什么把房間識別成了book...
faster-RCNN模型
faster-RCNN臼疫,加載模型83s择份,內(nèi)存不夠,跑不起來烫堤。荣赶。。
mask SSD模型
mask模型可以描繪出輪廓鸽斟,看起來更高端拔创,加載模型25s,遇到個問題:
接下來查一下
CPU占用率100%富蓄,內(nèi)存占用60%多