利用Tensorflow構建自己的物體識別模型(一)

原料

windows10+python3.5+pycharm

安裝tensorflow

利用Tensorflow訓練搭建自己的物體訓練模型,萬里長征第一步喊崖,先安裝tensorflow。

tensorflow分為cpu版和gpu版雇逞,gpu版的運行速度是cpu的50倍荤懂,但是gpu版的坑太多,要安裝許多開發(fā)套件,對windows的支持不夠友好塘砸;更為致命的是,它需要Nvida的中高端顯卡节仿,我的電腦系統(tǒng)是windows10,顯卡是入門級顯卡,開始我還想掙扎一下掉蔬,安裝個gpu版廊宪,大概試了一個晚上,到底是沒有成功女轿,識時務者為俊杰箭启,那就安裝cpu版的吧。

pip insatll tensorflow

假如沒有報錯蛉迹,做個測試册烈,運行以下代碼

import tensorflow as tf
#指定一個常數張量
first_blood = tf.constant('double kill')
#創(chuàng)建一個會話,方便查看結果
sess = tf.Session()
print(str(sess.run(first_blood)))

運行結果如下

E:\python\python.exe "E:/pycharm src/TF/__init__.py"
2018-12-01 23:33:25.181550: I tensorflow/core/platform/cpu_feature_guard.cc:141] Your CPU supports instructions that this TensorFlow binary was not compiled to use: AVX2
double kill

Process finished with exit code 0

如果出現警告:

Your CPU supports instructions that this TensorFlow binary was not compiled to use: AVX2

翻譯過來的大致意思是:
你的CPU支持AVX擴展婿禽,但是你安裝的TensorFlow版本無法編譯使用

此時需要在第一行代碼前加上兩行代碼:

import os
os.environ['TF_CPP_MIN_LOG_LEVEL'] = '2'
import tensorflow as tf
# 指定一個常數張量
first_blood = tf.constant('double kill')
# 創(chuàng)建一個會話,方便查看結果
sess = tf.Session()
print(str(sess.run(first_blood)))

下載Tensorflow object detection API

如果有git的話大猛,右鍵git bash,使用命令下載:

git clone https://github.com/tensorflow/models.git

或者直接打開網站:

https://github.com/tensorflow/models

點擊綠色按鈕->downlaod zip

下載好之后扭倾,把文件解壓,注意解壓路徑不要包含中文挽绩,比如我的解壓后的路徑是:

C:\Users\lenovo\Desktop\note\gitclone\models

如果下載速度很慢膛壹,可以參考:https://blog.csdn.net/ygdxt/article/details/82825013

下載并配置protoc

https://github.com/google/protobuf/releases中選擇windows版本:

1.png

只有win32,也就是windows32位的,64位是兼容32位的唉堪。

下載好之后模聋,解壓,把bin目錄下的protoc.exe復制到..\models\research文件夾下唠亚。

接著就是配置protoc了链方,在打開cmd下切換到..\models\research目錄,

執(zhí)行命令protoc object_detection\protos\*.proto --python_out=.

如果報以下的錯(其實很大可能性會報錯灶搜,無論是不是在管理員模式下):

object_detection\protos*.proto: No such file or directory

則需要對指令做修改祟蚀,指令protoc object_detection\protos\*.proto --python_out=.中的*.proto表示是對research目錄下的所有后綴名為proto的文件做操作工窍,那干脆我們把指令中的*.proto這部分改成所有后綴名為proto的文件,每執(zhí)行一次前酿,就會生成一個.py文件患雏,由于文件太多,我已經把指令寫成腳本:

import os

path_url = os.path.join(os.getcwd(),r"object_detection\protos")
print("proto path:",path_url)

for file in os.listdir(path_url):
    cmd = "protoc object_detection\protos\{} --python_out=."
    if file.endswith(".proto"):
        command = cmd.format(file)
        print("excuting command:",command)
        os.popen(command)

..\research目錄下新建一個文件excuter.py,把以上代碼復制進去罢维,保存運行淹仑,稍等一會兒就可以看到..\research\object_detection\protos目錄下生成了許多.py文件,說明protoc配置成功肺孵。

models環(huán)境變量配置

配置環(huán)境變量

依次打開:我的電腦--->高級系統(tǒng)設置--->環(huán)境變量匀借,新建一個系統(tǒng)變量:

2.png

3.png

系統(tǒng)變量名只要不和已有的重復,符合命令規(guī)范悬槽,沒有其他要求怀吻,我這里是tensorflow
系統(tǒng)變量名下有兩個值,..\research..\research\slim的絕對路徑。

測試

..\research下打開cmd初婆,運行以下命令蓬坡,

python object_detection/builders/model_builder_test.py

如果出現錯誤:

4.png

報錯原因是你的models路徑太長,python無法找指定模塊磅叛,
解決辦法是在你的python安裝路徑下新建一個tensorflow_model.pth文件
(比如我的是E:\python\Lib\site-packages)
把寫到環(huán)境變量里的那兩個路徑復制到該文件中屑咳。

5.png

再運行命令python object_detection/builders/model_builder_test.py

6.png

說明配置成功

利用tensorflow自帶模型測試

測試的圖片是在

C:\Users\lenovo\Desktop\note\gitclone\models\research\object_detection\test_images

我們看到這里有現成的兩張圖片,當然也可以換成自己的弊琴。

測試的腳本是

C:\Users\lenovo\Desktop\note\gitclone\models\research\object_detection\object_detection_tutorial.ipynb

這是一個需要用jupyter notebook打開的文件兆龙,不過好像在jupyter notebook運行會有許多毛病
我已經把這個ipynb文件改寫成py文件,并修復了一些未知問題敲董,文件內容如下:

import numpy as np
import os
import six.moves.urllib as urllib
import sys
import tarfile
import tensorflow as tf
import zipfile

from distutils.version import StrictVersion
from collections import defaultdict
from io import StringIO
from matplotlib import pyplot as plt
from PIL import Image

# This is needed since the notebook is stored in the object_detection folder.
sys.path.append("..")
from object_detection.utils import ops as utils_ops

if StrictVersion(tf.__version__) < StrictVersion('1.9.0'):
  raise ImportError('Please upgrade your TensorFlow installation to v1.9.* or later!')



import numpy as np
import os
import six.moves.urllib as urllib
import sys
import tarfile
import tensorflow as tf
import zipfile

from distutils.version import StrictVersion
from collections import defaultdict
from io import StringIO
from matplotlib import pyplot as plt
from PIL import Image

# This is needed since the notebook is stored in the object_detection folder.
sys.path.append("..")
from object_detection.utils import ops as utils_ops

if StrictVersion(tf.__version__) < StrictVersion('1.9.0'):
  raise ImportError('Please upgrade your TensorFlow installation to v1.9.* or later!')



from utils import label_map_util

from utils import visualization_utils as vis_util




# What model to download.
MODEL_NAME = 'ssd_mobilenet_v1_coco_2017_11_17'
MODEL_FILE = MODEL_NAME + '.tar.gz'
DOWNLOAD_BASE = 'http://download.tensorflow.org/models/object_detection/'

# Path to frozen detection graph. This is the actual model that is used for the object detection.
PATH_TO_FROZEN_GRAPH = 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('data', 'mscoco_label_map.pbtxt')



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())




detection_graph = tf.Graph()
with detection_graph.as_default():
  od_graph_def = tf.GraphDef()
  with tf.gfile.GFile(PATH_TO_FROZEN_GRAPH, 'rb') as fid:
    serialized_graph = fid.read()
    od_graph_def.ParseFromString(serialized_graph)
    tf.import_graph_def(od_graph_def, name='')



category_index = label_map_util.create_category_index_from_labelmap(PATH_TO_LABELS, use_display_name=True)



def load_image_into_numpy_array(image):
  (im_width, im_height) = image.size
  return np.array(image.getdata()).reshape(
      (im_height, im_width, 3)).astype(np.uint8)



# For the sake of simplicity we will use only 2 images:
# image1.jpg
# image2.jpg
# If you want to test the code with your images, just add path to the images to the TEST_IMAGE_PATHS.
PATH_TO_TEST_IMAGES_DIR = 'test_images'
TEST_IMAGE_PATHS = [ os.path.join(PATH_TO_TEST_IMAGES_DIR, 'image{}.jpg'.format(i)) for i in range(1, 3) ]

# Size, in inches, of the output images.
IMAGE_SIZE = (12, 8)

output_num = 1
output_img_dic = r'\output_images'


def run_inference_for_single_image(image, graph):
  with graph.as_default():
    with tf.Session() as sess:
      # Get handles to input and output tensors
      ops = tf.get_default_graph().get_operations()
      all_tensor_names = {output.name for op in ops for output in op.outputs}
      tensor_dict = {}
      for key in [
          'num_detections', 'detection_boxes', 'detection_scores',
          'detection_classes', 'detection_masks'
      ]:
        tensor_name = key + ':0'
        if tensor_name in all_tensor_names:
          tensor_dict[key] = tf.get_default_graph().get_tensor_by_name(
              tensor_name)
      if 'detection_masks' in tensor_dict:
        # The following processing is only for single image
        detection_boxes = tf.squeeze(tensor_dict['detection_boxes'], [0])
        detection_masks = tf.squeeze(tensor_dict['detection_masks'], [0])
        # Reframe is required to translate mask from box coordinates to image coordinates and fit the image size.
        real_num_detection = tf.cast(tensor_dict['num_detections'][0], tf.int32)
        detection_boxes = tf.slice(detection_boxes, [0, 0], [real_num_detection, -1])
        detection_masks = tf.slice(detection_masks, [0, 0, 0], [real_num_detection, -1, -1])
        detection_masks_reframed = utils_ops.reframe_box_masks_to_image_masks(
            detection_masks, detection_boxes, image.shape[0], image.shape[1])
        detection_masks_reframed = tf.cast(
            tf.greater(detection_masks_reframed, 0.5), tf.uint8)
        # Follow the convention by adding back the batch dimension
        tensor_dict['detection_masks'] = tf.expand_dims(
            detection_masks_reframed, 0)
      image_tensor = tf.get_default_graph().get_tensor_by_name('image_tensor:0')

      # Run inference
      output_dict = sess.run(tensor_dict,
                             feed_dict={image_tensor: np.expand_dims(image, 0)})

      # all outputs are float32 numpy arrays, so convert types as appropriate
      output_dict['num_detections'] = int(output_dict['num_detections'][0])
      output_dict['detection_classes'] = output_dict[
          'detection_classes'][0].astype(np.uint8)
      output_dict['detection_boxes'] = output_dict['detection_boxes'][0]
      output_dict['detection_scores'] = output_dict['detection_scores'][0]
      if 'detection_masks' in output_dict:
        output_dict['detection_masks'] = output_dict['detection_masks'][0]
  return output_dict




for image_path in TEST_IMAGE_PATHS:
  image = Image.open(image_path)
  # the array based representation of the image will be used later in order to prepare the
  # result image with boxes and labels on it.
  image_np = load_image_into_numpy_array(image)
  # Expand dimensions since the model expects images to have shape: [1, None, None, 3]
  image_np_expanded = np.expand_dims(image_np, axis=0)
  # Actual detection.
  output_dict = run_inference_for_single_image(image_np, detection_graph)
  # Visualization of the results of a detection.
  vis_util.visualize_boxes_and_labels_on_image_array(
      image_np,
      output_dict['detection_boxes'],
      output_dict['detection_classes'],
      output_dict['detection_scores'],
      category_index,
      instance_masks=output_dict.get('detection_masks'),
      use_normalized_coordinates=True,
      line_thickness=8)
  plt.figure(figsize=IMAGE_SIZE)
  print(1,image_np)
  plt.imshow(image_np)
  plt.show()
  global output_num
  global output_img_dic
  if not os.path.exists(output_img_dic):
      os.mkdir(output_img_dic)
  output_img_path = os.path.join(output_img_dic,str(output_num)+".png")
  plt.savefig(output_img_path)

運行上述代碼需要安裝matplotlib庫紫皇,直接pip install matplotlib安裝失敗的可以去官網安裝與python版本對應的whl文件。安裝matplotlib.whl時需要先出pycharm腋寨。
同時由于需要下載模型文件聪铺,需要在網絡好的情況下進行測試。否則就會報HTTP ERROR錯誤

運行效果圖

7.png

8.png
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末萄窜,一起剝皮案震驚了整個濱河市铃剔,隨后出現的幾起案子,更是在濱河造成了極大的恐慌查刻,老刑警劉巖键兜,帶你破解...
    沈念sama閱讀 211,123評論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現場離奇詭異穗泵,居然都是意外死亡普气,警方通過查閱死者的電腦和手機,發(fā)現死者居然都...
    沈念sama閱讀 90,031評論 2 384
  • 文/潘曉璐 我一進店門佃延,熙熙樓的掌柜王于貴愁眉苦臉地迎上來棋电,“玉大人茎截,你說我怎么就攤上這事「峡” “怎么了企锌?”我有些...
    開封第一講書人閱讀 156,723評論 0 345
  • 文/不壞的土叔 我叫張陵,是天一觀的道長于未。 經常有香客問我撕攒,道長,這世上最難降的妖魔是什么烘浦? 我笑而不...
    開封第一講書人閱讀 56,357評論 1 283
  • 正文 為了忘掉前任抖坪,我火速辦了婚禮,結果婚禮上闷叉,老公的妹妹穿的比我還像新娘擦俐。我一直安慰自己,他們只是感情好握侧,可當我...
    茶點故事閱讀 65,412評論 5 384
  • 文/花漫 我一把揭開白布蚯瞧。 她就那樣靜靜地躺著,像睡著了一般品擎。 火紅的嫁衣襯著肌膚如雪埋合。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,760評論 1 289
  • 那天萄传,我揣著相機與錄音甚颂,去河邊找鬼。 笑死秀菱,一個胖子當著我的面吹牛振诬,可吹牛的內容都是我干的。 我是一名探鬼主播衍菱,決...
    沈念sama閱讀 38,904評論 3 405
  • 文/蒼蘭香墨 我猛地睜開眼贷揽,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了梦碗?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 37,672評論 0 266
  • 序言:老撾萬榮一對情侶失蹤蓖救,失蹤者是張志新(化名)和其女友劉穎洪规,沒想到半個月后,有當地人在樹林里發(fā)現了一具尸體循捺,經...
    沈念sama閱讀 44,118評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡斩例,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 36,456評論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現自己被綠了从橘。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片念赶。...
    茶點故事閱讀 38,599評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡础钠,死狀恐怖,靈堂內的尸體忽然破棺而出叉谜,到底是詐尸還是另有隱情旗吁,我是刑警寧澤,帶...
    沈念sama閱讀 34,264評論 4 328
  • 正文 年R本政府宣布停局,位于F島的核電站很钓,受9級特大地震影響,放射性物質發(fā)生泄漏董栽。R本人自食惡果不足惜码倦,卻給世界環(huán)境...
    茶點故事閱讀 39,857評論 3 312
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望锭碳。 院中可真熱鬧袁稽,春花似錦、人聲如沸擒抛。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,731評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽闻葵。三九已至民泵,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間槽畔,已是汗流浹背栈妆。 一陣腳步聲響...
    開封第一講書人閱讀 31,956評論 1 264
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留厢钧,地道東北人鳞尔。 一個月前我還...
    沈念sama閱讀 46,286評論 2 360
  • 正文 我出身青樓,卻偏偏與公主長得像早直,于是被迫代替她去往敵國和親寥假。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 43,465評論 2 348

推薦閱讀更多精彩內容