基于Tensorflow的自定義對象識別檢測模型的訓(xùn)練及視頻實(shí)時(shí)識別(一)

開題

經(jīng)歷了近一周的摸索,Tensorflow這個(gè)深度學(xué)習(xí)框架读规,也算是有一個(gè)了結(jié)抓督,總結(jié)一下吧!
這個(gè)流程一下子看上去涉及的東西的確是很大的束亏,所以細(xì)分為以下步驟:

一铃在、 Python 、Tensorflow 安裝及環(huán)境配置
二碍遍、 Object Detection API配置
三、 LabelImage對訓(xùn)練樣本標(biāo)注處理
四揣炕、 標(biāo)注后訓(xùn)練樣本驗(yàn)證樣本格式轉(zhuǎn)換tfrecord
五东跪、 訓(xùn)練模型選取及參數(shù)配置
六畸陡、 定位在Object Detection文件下train.py開始訓(xùn)練
七、 上一步訓(xùn)練結(jié)果固化成pb模型
八虽填、 視頻流中調(diào)用模型預(yù)測

下面的文章我也將對以上步驟從個(gè)人開發(fā)角度闡述下:

一、python 牲览、tensorflow的安裝問題此處不做說明(tensorflow我用的cpu版本、IDE:PyCharm)

二桑驱、關(guān)于 Object Detection API的配置

1竭恬、請前往官方地址下載 https://github.com/tensorflow/models
發(fā)現(xiàn)現(xiàn)在通過git和直接download下載很慢甚至下載一半就掛掉了,所以百度網(wǎng)盤提供目前我訓(xùn)練用的models文件(非最新版)獲取連接如下:
鏈接:https://pan.baidu.com/s/14lKw1nos0quZ4P7LetOVvg
提取碼:4i6d

TIM截圖20190424152625.png

下面操作都是在models/research下

2、在 https://github.com/google/protobuf/releases 網(wǎng)站中選擇windows 版本(最下面)押框,解壓后將bin文件夾中的protoc.exe放到C:\Windows下或?qū)in加入環(huán)境變量如:D:\protoc-3.4.0-win32\bin加入path中

進(jìn)入models\research\目錄下 按shift + 右鍵 打開命令行窗口理逊,輸入:

protoc object_detection/protos/*.proto --python_out=.

對proto文件進(jìn)行編譯盒揉,完成后會生成對應(yīng)名稱的py腳本文件

3兑徘、將models\reserach 和models\research\slim 加入環(huán)境變量

4、驗(yàn)證環(huán)境:
在models\research下 按shift + 右鍵 開啟命令行輸入

python object_detection/builders/model_builder_test.py

等待一秒左右藕漱,若下方出現(xiàn) ok 字樣 不報(bào)錯崭闲,說明環(huán)境配置成功

5、跑通官方示例:
在PyCharm下打開終端定位到models\research\object_detection下 輸入

jupyter-notebook

將自動打開瀏覽器如下


TIM截圖20190424154438.png
TIM截圖20190424155200.png

點(diǎn)擊上方標(biāo)記的object_detection_tutorial.ipynb 進(jìn)入可編輯腳本處理頁


TIM截圖20190424155438.png

點(diǎn)擊Run All 等待一會,第一次執(zhí)行會從腳本鏈接中下載模型所以可能慢很多侮繁,若當(dāng)前標(biāo)簽頁一直處于
TIM截圖20190424155642.png

說明腳本仍在執(zhí)行中如孝,耐心等待沙漏消失暑竟,運(yùn)行完畢后最下方可見【狗】和【滑翔傘】圖片識別結(jié)果


TIM截圖20190424160154.png

此處便是關(guān)于模型調(diào)用的官方樣例,以后關(guān)于視頻流的實(shí)時(shí)監(jiān)測也將在此基礎(chǔ)上優(yōu)化罗岖,這也是后話了腹躁,后面在介紹吧!

三纺非、自定義對象處理

1、訓(xùn)練樣品及驗(yàn)證樣品圖片標(biāo)注

官方下載地址LabelImage 下載地址https://github.com/tzutalin/labelImg/releases
解壓放在非中文路徑下弱左,新建文件夾分別保存訓(xùn)練和驗(yàn)證圖片炕淮、標(biāo)注后訓(xùn)練和驗(yàn)證的xml

TIM截圖20190424161428.png

TIM截圖20190424161437.png

雙擊labelImage.exe
TIM截圖20190424162403.png

(綠色的背景剛好影響了標(biāo)注框,不太明顯)

  1. Open Dir 選擇要標(biāo)記的圖片源
  2. Change Save Dir 選擇標(biāo)記后要保存xml的路徑
  3. 下一張币叹、上一張模狭、保存
  4. Create RextBox 點(diǎn)擊開始標(biāo)記
  5. raccoon 為標(biāo)簽,即要識別的物體名稱(如:dog cat person car...)

注:對圖片標(biāo)注不僅僅是體力活贩汉,其實(shí)也是技術(shù)活反砌,打標(biāo)區(qū)域不僅需要涵蓋物體可見區(qū)域,還要盡量減少無關(guān)背景在存在

2策菜、xml標(biāo)注文件轉(zhuǎn)tfrecord

import os
import glob
import pandas as pd
import xml.etree.ElementTree as ET


def xml_to_csv(path):
    xml_list = []
    for xml_file in glob.glob(path + '/*.xml'):
        tree = ET.parse(xml_file)
        root = tree.getroot()
        for member in root.findall('object'):
            value = (root.find('filename').text,
                     int(root.find('size')[0].text),
                     int(root.find('size')[1].text),
                     member[0].text,
                     int(member[4][0].text),
                     int(member[4][1].text),
                     int(member[4][2].text),
                     int(member[4][3].text)
                     )
            xml_list.append(value)
    column_name = ['filename', 'width', 'height', 'class', 'xmin', 'ymin', 'xmax', 'ymax']
    xml_df = pd.DataFrame(xml_list, columns=column_name)
    return xml_df


def main():
    # xml文件的路徑
    image_path = os.path.join(os.getcwd(), 'data/train_xml')
    xml_df = xml_to_csv(image_path)
    # 輸出路徑
    xml_df.to_csv('data/train.csv', index=None)
    print('Successfully converted annotations  xml to csv.')

    image_path = os.path.join(os.getcwd(), data/'test_xml')
    xml_df = xml_to_csv(image_path)
    # 輸出路徑
    xml_df.to_csv('data/text.csv', index=None)
    print('Successfully converted  textxml  xml to csv.')


main()

將上一步訓(xùn)練和驗(yàn)證csv文件轉(zhuǎn)換tfrecord

from __future__ import division
from __future__ import print_function
from __future__ import absolute_import

import os
import io
import pandas as pd
import tensorflow as tf

from PIL import Image
from object_detection.utils import dataset_util
from collections import namedtuple, OrderedDict

flags = tf.app.flags
# 幾個(gè)輸入的參數(shù)又憨,
# python generate_tfrecord.py --csv_input=data/train_labels.csv --output_path=test/data/train.record --image_dir=images
flags.DEFINE_string('csv_input', '', 'Path to the CSV input')
flags.DEFINE_string('output_path', '', 'Path to output TFRecord')
flags.DEFINE_string('image_dir', '', 'Path to images')
FLAGS = flags.FLAGS


# TO-DO replace this with label map
# 改成你的類別  有幾個(gè)分類就往下依次進(jìn)行(return 1  return  2  ........  else  return 0)
def class_text_to_int(row_label):
    if row_label == 'raccoon':  # raccoon
        return 1
    else:
        return 0


def split(df, group):
    data = namedtuple('data', ['filename', 'object'])
    gb = df.groupby(group)
    return [data(filename, gb.get_group(x)) for filename, x in zip(gb.groups.keys(), gb.groups)]


def create_tf_example(group, path):
    with tf.gfile.GFile(os.path.join(path, '{}'.format(group.filename)), 'rb') as fid:
        encoded_jpg = fid.read()
    encoded_jpg_io = io.BytesIO(encoded_jpg)
    image = Image.open(encoded_jpg_io)
    width, height = image.size

    filename = group.filename.encode('utf8')
    image_format = b'jpg'
    xmins = []
    xmaxs = []
    ymins = []
    ymaxs = []
    classes_text = []
    classes = []

    for index, row in group.object.iterrows():
        xmins.append(row['xmin'] / width)
        xmaxs.append(row['xmax'] / width)
        ymins.append(row['ymin'] / height)
        ymaxs.append(row['ymax'] / height)
        classes_text.append(row['class'].encode('utf8'))
        classes.append(class_text_to_int(row['class']))

    tf_example = tf.train.Example(features=tf.train.Features(feature={
        'image/height': dataset_util.int64_feature(height),
        'image/width': dataset_util.int64_feature(width),
        'image/filename': dataset_util.bytes_feature(filename),
        'image/source_id': dataset_util.bytes_feature(filename),
        'image/encoded': dataset_util.bytes_feature(encoded_jpg),
        'image/format': dataset_util.bytes_feature(image_format),
        'image/object/bbox/xmin': dataset_util.float_list_feature(xmins),
        'image/object/bbox/xmax': dataset_util.float_list_feature(xmaxs),
        'image/object/bbox/ymin': dataset_util.float_list_feature(ymins),
        'image/object/bbox/ymax': dataset_util.float_list_feature(ymaxs),
        'image/object/class/text': dataset_util.bytes_list_feature(classes_text),
        'image/object/class/label': dataset_util.int64_list_feature(classes),
    }))
    return tf_example


def main(_):
    writer = tf.python_io.TFRecordWriter(FLAGS.output_path)
    path = os.path.join(FLAGS.image_dir)
    examples = pd.read_csv(FLAGS.csv_input)
    grouped = split(examples, 'filename')
    for group in grouped:
        tf_example = create_tf_example(group, path)
        writer.write(tf_example.SerializeToString())

    writer.close()
    output_path = os.path.join(os.getcwd(), FLAGS.output_path)
    print('Successfully created the TFRecords: {}'.format(output_path))


if __name__ == '__main__':
    tf.app.run()

'''
cd 到generate_tfrecord.py該文件目錄下
執(zhí)行命令:python generate_tfrecord.py --csv_input=data/train_labels.csv --output_path=test/data/train.record --image_dir=images
解釋:
python generate_tfrecord.py --csv_input=[train_labels.csv的路徑] --output_path=[輸出train.record的路徑] --image_dir=[輸入圖片的路徑]
最終得到:
train.record 和 test.record

注:在xml 轉(zhuǎn)csv 和csv轉(zhuǎn)tfrecord過程中 若出現(xiàn)錯誤,請檢查
1. 圖片和xml 是否一 一 對 應(yīng)
2. 路徑問題零如,最為保險(xiǎn)的是絕對路徑和雙斜杠 如:D:\PyCharm\raccoon_dataset_sample\testimg
r 、t祸憋、n等開頭的直接雙斜杠處理省得有歧義
3. 有幾個(gè)分類標(biāo)簽就依次對應(yīng)下來

結(jié)語:

由于篇幅限制這篇就到這里吧肖卧,下一篇在繼續(xù)吧!

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末拦赠,一起剝皮案震驚了整個(gè)濱河市葵姥,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌颊咬,老刑警劉巖牡辽,帶你破解...
    沈念sama閱讀 216,402評論 6 499
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件态辛,死亡現(xiàn)場離奇詭異,居然都是意外死亡奏黑,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,377評論 3 392
  • 文/潘曉璐 我一進(jìn)店門馁害,熙熙樓的掌柜王于貴愁眉苦臉地迎上來蹂匹,“玉大人限寞,你說我怎么就攤上這事÷闹玻” “怎么了?”我有些...
    開封第一講書人閱讀 162,483評論 0 353
  • 文/不壞的土叔 我叫張陵凿滤,是天一觀的道長庶近。 經(jīng)常有香客問我,道長鹃祖,這世上最難降的妖魔是什么普舆? 我笑而不...
    開封第一講書人閱讀 58,165評論 1 292
  • 正文 為了忘掉前任,我火速辦了婚禮祖能,結(jié)果婚禮上蛾洛,老公的妹妹穿的比我還像新娘雁芙。我一直安慰自己钞螟,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,176評論 6 388
  • 文/花漫 我一把揭開白布洞焙。 她就那樣靜靜地躺著拯啦,像睡著了一般。 火紅的嫁衣襯著肌膚如雪唁情。 梳的紋絲不亂的頭發(fā)上甫匹,一...
    開封第一講書人閱讀 51,146評論 1 297
  • 那天,我揣著相機(jī)與錄音哀墓,去河邊找鬼喷兼。 笑死,一個(gè)胖子當(dāng)著我的面吹牛吠各,可吹牛的內(nèi)容都是我干的勉抓。 我是一名探鬼主播,決...
    沈念sama閱讀 40,032評論 3 417
  • 文/蒼蘭香墨 我猛地睜開眼纵散,長吁一口氣:“原來是場噩夢啊……” “哼隐圾!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起暇藏,我...
    開封第一講書人閱讀 38,896評論 0 274
  • 序言:老撾萬榮一對情侶失蹤盐碱,失蹤者是張志新(化名)和其女友劉穎沪伙,沒想到半個(gè)月后县好,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,311評論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡某饰,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,536評論 2 332
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了诫尽。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,696評論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡剂跟,死狀恐怖酣藻,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情送淆,我是刑警寧澤怕轿,帶...
    沈念sama閱讀 35,413評論 5 343
  • 正文 年R本政府宣布,位于F島的核電站阐斜,受9級特大地震影響诀紊,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜邻奠,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,008評論 3 325
  • 文/蒙蒙 一惕澎、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧唧喉,春花似錦忍抽、人聲如沸董朝。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,659評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽哥捕。三九已至,卻和暖如春扬舒,著一層夾襖步出監(jiān)牢的瞬間凫佛,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,815評論 1 269
  • 我被黑心中介騙來泰國打工晨炕, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留毫炉,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 47,698評論 2 368
  • 正文 我出身青樓遵馆,卻偏偏與公主長得像丰榴,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個(gè)殘疾皇子四濒,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,592評論 2 353

推薦閱讀更多精彩內(nèi)容