ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

【CV】目标检测(Tensorflow_API_SSD)

2020-01-31 10:40:51  阅读:381  来源: 互联网

标签:API training object list detection 文件夹 Tensorflow SSD path


目录


0.运行tensorflow官方示例:

本文基于window10,python3.6 ,tensorflow1.12。在官网model里的research文件夹 :https://github.com/tensorflow/models/tree/master/research
1.window下载子目录:object_detection文件夹右击复制链接地址将/branches/branchname/替换成/trunk/,下载TortoiseSVN软件,桌面新建文件夹选中右击svn checkout。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
2.ubuntu下载子目录:安装svn:sudo apt-get install subversion,同上改为trunk,新文件夹里命令$svn checkout +改后地址。
3.ubuntu下载单文件:wget+含raw的新地址
在这里插入图片描述

1.proto文件转py文件

Protobuf是google开发的的一套用于数据存储,网络通信时用于协议编解码的工具库。它和XML和Json数据差不多,把数据以某种形式保存起来。不同之处,它是一种二进制的数据格式,具有更高的传输,打包和解包效率。下载Protobuf网址:https://github.com/google/protobuf/releases 下载压缩文件protoc-3.7.0-win64.zip,解压后将bin文件夹中protoc.exe复制到c/window,在工程object_detection文件夹中,进入文件夹protos,文件夹中有很多以proto为后缀的文件,把这些proto文件转换为py文件。与工程object_detection文件夹同级目录中,打开cmd,不进入object_detection文件夹,运行jupyter notebook,新建一个ipynb文件,即点击选择New->Python3,复制下面一段代码运行:

import os
file_list = os.listdir('object_detection/protos/')
proto_list = [file for file in file_list if '.proto' in file]
print('object_detection/proto文件夹中共有%d个proto文件' %len(proto_list))
for proto in proto_list:
    execute_command = 'protoc object_detection/protos/%s --python_out=.' %proto
    os.popen(execute_command) # 相当于cmd直接打开路径
file_list = os.listdir('object_detection/protos/')
py_list = [file for file in file_list if '.py' in file]
print('通过protoc命令产生的py文件共有%d个' %(len(py_list) - 1))

重进入文件夹object_detection/protos,文件夹中每个proto文件后都有一个py文件,即将proto文件转py文件成功。
在这里插入图片描述

2.下载模型并运行ipynb文件

object_detection_tutorial.ipynb中有下载预训练好的模型的代码语句。代码可以运行,但是无法得到结果,因为代码中的下载链接是国外的网址,所以下文删除代码中Download Model块,本人提供百度云盘:链接:https://pan.baidu.com/s/1a4u-Xeu8KDKABlE6DfmM3Q 提取码:ek3n 。将下载好的压缩文件放到工程object_detection文件夹中并解压:文件夹ssd_mobilenet_v1_coco_2017_11_17中有文件夹saved_model文件夹和6个文件
在工程object_detection文件夹中运行cmd,打开jupter notebook,运行下面文件:
在这里插入图片描述
删除代码块,再run all 模块:
在这里插入图片描述
作者本人在运行时出现两个报错:
1.删除红色框中内容,运行成功
在这里插入图片描述

2.pillow库版本之前-U升级过,版本过高,按提示安装旧版:先pip uninstall,再用阿里云镜像安装:
在这里插入图片描述

3.tf_SSD

win10深度学习环境:https://blog.csdn.net/weixin_43435675/article/details/88359636 ,桌面新建目标检测2文件夹,以下为本次项目会用到的文件:
在这里插入图片描述
本文作者给读者演示的图片数据是来自ImageNet中的鲤鱼分类
链接:https://pan.baidu.com/s/17iI62gt9HyRbQ-Wr8h28jw 提取码:4swb

4. 挑选图片

此数据集中大部分图片都较为清晰,但极少数图片像素点少不清晰。像素点少的图片不利于模型训练或模型测试,在目标检测2文件夹中cmd,打开jupyter notebook,新建重命名为:get_some_qualified_images,运行下一段代码后会在目标检测2文件夹下多出selected_images文件夹

import os
import random
from PIL import Image
import shutil

#获取1000张图片中随机选出数量为sample_number*2的一部分图片的路径
def get_some_imagePath(dirPath, sample_number):
    fileName_list = os.listdir(dirPath)
    all_filePath_list = [os.path.join(dirPath, fileName) for fileName in fileName_list]#绝对路径
    all_imagePath_list = [filePath for filePath in all_filePath_list if '.jpg' in filePath] #获得.jpg后缀的绝对路径
    some_filePath_list = random.sample(all_filePath_list, k=sample_number*2)#随机获取k个元素还是返回列表
    return some_filePath_list

#获取一部分像素足够,即长,宽都大于300的图片放入new_dirPath文件夹中
def get_some_qualified_images(dirPath, sample_number, new_dirPath):
    some_imagePath_list = get_some_imagePath(dirPath, sample_number)
    if not os.path.isdir(new_dirPath):
        os.mkdir(new_dirPath)
    i = 0
    for imagePath in some_imagePath_list:
        image = Image.open(imagePath)
        width, height = image.size
        if width > 300 and height > 300:
            i += 1
            new_imagePath = 'selected_images/%03d.jpg' %i
            shutil.copy(imagePath, new_imagePath)
        if i == sample_number:
            break
            
#获取数量为100的合格样本存放到selected_images文件夹中
get_some_qualified_images('n01440764', 100, 'selected_images')

5.缩小图片

选出了100张像素足够的图片存放在selected_images文件夹中,本章中用代码实现将像素过大的图片做缩小:新建文件get_small_images.ipynb,运行下段代码:

import os
from PIL import Image

def get_smaller_images(dirPath, new_dirPath): #参数自己传入与上文无关
    fileName_list = os.listdir(dirPath)
    filePath_list = [os.path.join(dirPath, fileName) for fileName in fileName_list]
    imagePath_list = [filePath for filePath in filePath_list if '.jpg' in filePath]
    if not os.path.isdir(new_dirPath):
        os.mkdir(new_dirPath)
    for imagePath in imagePath_list:
        image = Image.open(imagePath)
        width, height = image.size
        imageName = imagePath.split('\\')[-1]
        save_path = os.path.join(new_dirPath, imageName)
        if width >= 600 and height >= 600:
            minification = min(width, height) // 300 #此变量表示缩小倍数
            new_width = width // minification
            new_height = height // minification
            resized_image = image.resize((new_width, new_height), Image.ANTIALIAS)
            print('图片%s原来的宽%d,高%d, 图片缩小后宽%d,高%d' %(
                imageName, width, height, new_width, new_height))
            resized_image.save(save_path)
        else:
            image.save(save_path)

get_smaller_images('selected_images', 'smaller_images')

图片经过PIL库打开再保存,保持图片质量的情况下,能够缩小图片文件大小3倍左右。

6.图片打标签

LabelImg链接:https://pan.baidu.com/s/1YT_s0Ef95fOJAsiG69Bmkw 提取码:6epi
把压缩文件windows_v1.8.0.zip放到D盘根目录中,选择解压到当前文件夹。解压后D盘根目录下会有windows_v1.8.0文件夹,LabelImg软件在文件夹中。选择D盘根目录的原因:如果windows_v1.8.0文件夹路径中带有中文,打开LabelImg软件会闪退
在这里插入图片描述
按W画框,voc格式为xml,ctrl+s保存,A和D上下张 ,ctrl+d复制
在这里插入图片描述
已经打标签好的文件夹smaller_images做成压缩文件smaller_images.zip,链接:https://pan.baidu.com/s/13-fRksSjUeEii54gClA3Pw 提取码:57lz

7.xml转csv,csv转tfrecord

目标检测2文件夹中新建代码文件xml_to_csv.ipynb,cmd——>运行jupyter notebook——>新建代码文件——>代码文件重命名,复制下面一段代码到代码文件xml_to_csv.ipynb并运行:

import os
import pandas as pd
import xml.etree.ElementTree as ET
from sklearn.model_selection import train_test_split

def xmlPath_list_to_df(xmlPath_list):
    xmlContent_list = []
    for xmlPath in xmlPath_list:
        tree = ET.parse(xmlPath)
        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)
                     )
            xmlContent_list.append(value)
    column_name = ['filename', 'width', 'height', 'class', 'xmin', 'ymin', 'xmax', 'ymax']
    xmlContent_df = pd.DataFrame(xmlContent_list, columns=column_name)   
    return xmlContent_df

def dirPath_to_csv(dirPath):
    fileName_list = os.listdir(dirPath)
    all_xmlPath_list = [os.path.join(dirPath, fileName) for fileName in fileName_list if '.xml' in fileName]
    train_xmlPath_list, test_xmlPath_list = train_test_split(all_xmlPath_list, test_size=0.1, random_state=1)
    train_df = xmlPath_list_to_df(train_xmlPath_list)
    train_df.to_csv('train.csv')
    print('成功产生文件train.csv,训练集共有%d张图片' %len(train_xmlPath_list))
    test_df = xmlPath_list_to_df(test_xmlPath_list)
    test_df.to_csv('test.csv')
    print('成功产生文件test.csv,测试集共有%d张图片' %len(test_xmlPath_list))
    
dirPath_to_csv('smaller_images')

为了使读者与本文作者的复现结果一致,本文作者将函数train_test_split的参数random_state的值设为1,这样每次划分的训练集和测试集总是相同。如果不设置此参数,则每次划分的训练集和测试集不同。上面一段代码的运行结果如下:

成功产生文件train.csv,训练集共有89张图片
成功产生文件test.csv,测试集共有10张图片

object_detection官网文件分享:链接:https://pan.baidu.com/s/19T5KCZxEKjzYJLQoWIc2qA 提取码:2zk3 ,桌面的目标检测2文件夹中新建代码文件csv_to_tfrecord.ipynb,打开cmd——>运行jupyter notebook——>新建代码文件——>代码文件重命名csv_to_tfrecord.ipynb,复制下代码运行:

import os
import pandas as pd
import tensorflow as tf
from object_detection.utils import dataset_util
import shutil

def csv2tfrecord(csv_path, imageDir_path, tfrecord_path):
    objectInfo_df = pd.read_csv(csv_path)
    tfrecord_writer = tf.python_io.TFRecordWriter(tfrecord_path)
    for filename, group in objectInfo_df.groupby('filename'):
        height = group.iloc[0]['height']
        width = group.iloc[0]['width']
        filename_bytes = filename.encode('utf-8')
        image_path = os.path.join(imageDir_path, filename)
        with open(image_path, 'rb') as file:
            encoded_jpg = file.read()
        image_format = b'jpg'
        xmin_list = list(group['xmin'] / width)
        xmax_list = list(group['xmax'] / width)
        ymin_list = list(group['ymin'] / height)
        ymax_list = list(group['ymax'] / height)
        classText_list = [classText.encode('utf-8') for classText in group['class']]
        classLabel_list = [classText_to_classLabel(classText) for classText in group['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_bytes),
                    'image/source_id': dataset_util.bytes_feature(filename_bytes),
                    '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(xmin_list),
                    'image/object/bbox/xmax': dataset_util.float_list_feature(xmax_list),
                    'image/object/bbox/ymin': dataset_util.float_list_feature(ymin_list),
                    'image/object/bbox/ymax': dataset_util.float_list_feature(ymax_list),
                    'image/object/class/text': dataset_util.bytes_list_feature(classText_list),
                    'image/object/class/label': dataset_util.int64_list_feature(classLabel_list),
                }))
        tfrecord_writer.write(tf_example.SerializeToString())
    tfrecord_writer.close()
    print('成功产生tfrecord文件,保存在路径:%s' %tfrecord_path)

#如果训练自己的模型,目标检测的类别不同,需要修改此处
def classText_to_classLabel(row_label):
    if row_label == 'fish':
        return 1
    elif row_label == 'human_face':
        return 2
    else:
        return None

dir_name = 'training'
if not os.path.isdir(dir_name):
    os.mkdir(dir_name)
csv2tfrecord('train.csv', 'smaller_images', 'training/train.tfrecord')
csv2tfrecord('test.csv', 'smaller_images', 'training/test.tfrecord')

运行结果:

成功产生tfrecord文件,保存在路径:training/train.tfrecord
成功产生tfrecord文件,保存在路径:training/test.tfrecord

成功运行后产生training文件夹:
在这里插入图片描述

8.编写pbtxt文件

在桌面文件夹目标检测2的文件夹training中,创建文本文件my_label_map.pbtxt。复制下面一段内容到文本文件my_label_map.pbtxt中。

item {
    name : "fish"
    id : 1
}
item {
    name : "human_face"
    id : 2
}

在这里插入图片描述
一个细节需注意,文本fish_label.pbtxt在Windows系统下默认编码格式是ANSI格式,工程中需要的就是此格式。但是本人认为python3对utf-8编码支持较好,所以把fish_label.pbtxt的编码改成了utf-8格式,导致报错。

9. 编写配置文件

在这里插入图片描述
在这里插入图片描述
ssdlite_mobilenet_v2_coco.config复制1份到目标检测2的文件夹training中,修改的部分为:
第9行的num_classes,对于本文来说,此数设置为2。
第143行的batch_size,对于本文来说,此数设置为5,读者根据自己的电脑配置,可以调高或者调低。
第177行input_path设置成"training/train.tfrecord"。
第179行label_map_path设置成"training/my_label_map.pbtxt"。
第191行input_path设置成"training/test.tfrecord"。
第193行label_map_path设置成"training/my_label_map.pbtxt"。
第158、159这2行需要删除。
修改保存后在training文件夹下有以下4个文件:
在这里插入图片描述

10.训练模型

10.1 解决第一个报错

在桌面文件夹目标检测2中cmd,运行程序:python object_detection/model_main.py --pipeline_config_path=training/ssdlite_mobilenet_v2_coco.config --model_dir=training --alsologtostderr
结果如下报错:
在这里插入图片描述
解决:新建环境变量在这里插入图片描述
新建变量名为:PYTHONPATH,全部点确定按钮
在这里插入图片描述

10.2 解决第二个报错

成功添加环境变量后,需要在桌面的目标检测文件夹中重新打开cmd。在cmd中运行命令:python object_detection/model_main.py --pipeline_config_path=training/ssdlite_mobilenet_v2_coco.config --model_dir=training --alsologtostderr,运行结果如下图所示:
在这里插入图片描述
缺少pycocotools库,在linux系统中安装pycocotools库只需要运行命令:pip install pycocotools,但是在Windows上安装则复杂得多

10.2.1 下载并安装Microsoft C++ build 14.0

首先下载Microsoft C++ build 14.0,链接:https://go.microsoft.com/fwlink/?LinkId=691126
在这里插入图片描述
在这里插入图片描述

10.2.2 下载并安装pycocotools

打开git页面,链接:https://github.com/philferriere/cocoapi
在这里插入图片描述
在这里插入图片描述
对压缩文件cocoapi-master.zip选择解压到当前文件夹。进入文件夹cocoapi-master中的文件夹PythonAPI,在此文件夹下打开cmd运行指令:python setup.py build_ext install
在这里插入图片描述
如下图安装成功:
在这里插入图片描述

10.3 解决第三个报错

进行完上面后,需要在桌面的目标检测文件夹中重新打开cmd。在cmd中运行命令:python object_detection/model_main.py --pipeline_config_path=training/ssdlite_mobilenet_v2_coco.config --model_dir=training --alsologtostderr,运行结果如下图所示:
在这里插入图片描述
解决此报错,需要阅读上文《proto文件转py文件》就是把object_detection/protos文件夹中将proto文件转py文件。

10.4 解决第四个报错

进行完第3章后,使用第3章中的cmd即可。在cmd中运行命令:python object_detection/model_main.py --pipeline_config_path=training/ssdlite_mobilenet_v2_coco.config --model_dir=training --alsologtostderr,运行结果如下图所示:
在这里插入图片描述
将models-master/research/slim文件夹中的nets文件夹移动到桌面的目标检测2文件夹中,即文件夹object_detection同级目录。因为models-master.zip大小为439M,但我们其实只要nets文件夹。
本文作者提供nets文件夹压缩后的压缩文件nets.zip: 链接:https://pan.baidu.com/s/18c4Ec6wfLRs-1RitxFQMzg 提取码:658j
在这里插入图片描述

10.5 解决第五个报错

在cmd中运行命令:python object_detection/model_main.py --pipeline_config_path=training/ssdlite_mobilenet_v2_coco.config --model_dir=training --alsologtostderr,运行结果如下图所示:
在这里插入图片描述
修改工程文件夹object_detection中的代码文件model_lib.py
如下图所示,找到第418行,将category_index.values()修改为list(category_index.values())
在这里插入图片描述
在cmd中重新输入命令开启模型训练
在这里插入图片描述

11.查看训练效果

模型训练稳定地进行后,在桌面的目标检测文件夹中重新打开cmd。在cmd中运行命令:tensorboard --logdir=training,出现下图,复制到浏览器中打开
在这里插入图片描述
在这里插入图片描述

12.模型测试

作者将如下三个文件合并做了压缩 链接:https://pan.baidu.com/s/18c4Ec6wfLRs-1RitxFQMzg 提取码:658j,解压后含以下三个文件夹,training文件夹里含已经训练好的20万次模型,将自己的目标检测2文件夹里object-detection和training替换成下载好的
在这里插入图片描述

12.1 导出训练好的模型

在目标检测2文件夹中打开cmd,运行python object_detection/export_inference_graph.py --input_type=image_tensor --pipeline_config_path=training/ssdlite_mobilenet_v2_coco.config --trained_checkpoint_prefix=training/model.ckpt-200000 --output_directory=fish_inference_graph
在这里插入图片描述
运行正常需要安装PYQT5这个库,pip install pyqt5即可安装好,此时目标检测2文件夹里多出了红色框出的文件夹在这里插入图片描述
在这里插入图片描述
如上图红色框出是测试图片数据集

12.2 下载并运行测试代码

检测代码文件:链接:https://pan.baidu.com/s/1wKrqnQCGfnHTS5n9nqZ_gw 提取码:vdj7
代码文件fish_detection.ipynb下载完成后,复制到桌面的文件夹目标检测2中,在目标检测2中打开cmd
输入jupyter notebook 并打开fish_detection.ipynb,如下图所示:
在这里插入图片描述
n01440764文件夹中共有1300张图片,测试图片是随机选的10张图片:
在这里插入图片描述

weixin_43435675 发布了89 篇原创文章 · 获赞 109 · 访问量 2万+ 私信 关注

标签:API,training,object,list,detection,文件夹,Tensorflow,SSD,path
来源: https://blog.csdn.net/weixin_43435675/article/details/88201615

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有