2020年tensorflow定制训练模型笔记(2)——制作标签

上一篇我们已经配置好了文件,接下来就是制作训练标签。我这次想做的是检测六个不同物体,是去年也就是2019年浙江的工程训练比赛的题目,因为我之前有拍过一大堆的数据。
检测物体分别为圆柱、N形方块、三角柱体、正方体、五角星柱体、六边形柱体。为了偷懒我把他们标注为123456,差不多对应他们的名字。之所以想到用深度学习的方法去检测,是因为传统的图像霍夫检测与机器学习无法完美适应环境,他们是有可能成功,但其中的不确定性太大了,准确率也低 。你无法避免环境因素、噪音干扰。
我之前也用过百度的easy dl做过,他们的算法很强大,做出来既快捷方便准确率又高。唯一的问题是他们好像只是针对企业,对学生群体不是很友好,而且我提交发布模型申请后,也根本没有人在几个工作日内鸟我。本着掌握关键技术的思想,我才决定自己学习定制模型的方法,这样以后要用上的时候就不会求人了。

1.准备工作

1.1在桌面上创建一个文件夹,例如命名’xx_object’,并在’xx_object’下创建四个文件夹分别命名为’train’,‘test’,‘training’,‘data’
在这里插入图片描述
1.2 将图片放入train文件夹中,实际上我们需要将图片分成train和test甚至val,但先为了方便操作,我们都放入train里。在这里插入图片描述
一般建议100张吧,80%train,20%test。这里给大家一些代码用来批量处理图片:

import os.path
import glob
import cv2
import numpy as np 

#全局统一大小处理
def convertjpg(jpgfile,outdir,width=600,height=800):
    
    src = cv2.imread(jpgfile, cv2.IMREAD_ANYCOLOR)
    
    try:
        dst = cv2.resize(src, (width,height), interpolation=cv2.INTER_CUBIC) 
        cv2.imwrite(os.path.join(outdir,os.path.basename(jpgfile)), dst)
    except Exception as e:
        print(e)
        
for jpgfile in glob.glob(r'C:\Users\kangaroo\Desktop\111\*.jpg'):# 修改为自己的路径
    convertjpg(jpgfile,r'C:\Users\kangaroo\Desktop\train')# 修改为自己的路径

#批量修改图片名字
import os 
def rename():
    #原始图片路径
    path = r'C:\Users\kangaroo\测试代码\视觉处理\11.21'# 修改为自己的路径
    #获取该路径下所有图片
    filelist = os.listdir(path)
    a = 42
    for files in filelist:
        #原始路径 
        Olddir = os.path.join(path,files)
        
        #if os.path.isdir(Olddir):
        #	continue
        #将图片名切片,比如 xxx.bmp 切成xxx和.bmp
        filename = os.path.splitext(files)[0]
        #.bmp
        filetype = os.path.splitext(files)[1]
        #需要存储的路径 a 是需要定义修改的文件名
        Newdir=os.path.join(path,str(a)+filetype)
        os.rename(Olddir,Newdir)
        a += 1
rename()

#统一灰度图与大小 处理
for j in range(1,20):
    img_gray = cv2.imread('11.20/%d.jpg'%j,cv2.IMREAD_GRAYSCALE) # 修改为自己的路径
    cropImg = cv2.resize(img_gray,(300,300))
    cv2.imwrite('chuli/%d.jpg'%j,cropImg)

准备结束,开始标注。
以上步骤只是为了方便我讲解步骤,也方便大家理解,大家理解后不一定要按我的方式来创建文件,我就按我所创建的文件名来说明

2.labelImg

2.1下载labelImg

我给出百度云:
链接:https://pan.baidu.com/s/1Uyt9_pVxhZDoQikXj2wMng
提取码:vk66

2.2标注信息

解压后打开,在文件夹下直接双击labelImg.exe。

在这里插入图片描述

出现此界面后,点击open dir,选择你要标注图片列表,也就是train文件夹
在这里插入图片描述
快捷键:

  • w: 画框
  • d:下一张
  • a:上一张
  • ctrl+s:保存

2.3分类照片

慢慢地把所有的图片标注好,会生成对应的xml文件,然后选取20%地图片放入test文件夹里
在这里插入图片描述

3.xml to csv

现在我们把整个’my_object’文件夹放到models/research/object_detection/ 这个目录下并运行下面的代码,将train和test下的xml文件分别合成csv文件,注意自己的路径 。

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():
    image_path = path
    xml_df = xml_to_csv(image_path)
    xml_df.to_csv(target, index=None)
    print('Successfully converted xml to csv.')

#生成test的csv文件,根据自己情况修改路径
path = 'models/research/object_detection/my_object/test'
target = 'test.csv'
os.chdir(path)
main()

#生成train的csv文件,根据自己情况修改路径
path = 'models/research/object_detection/my_object/train'
target = 'train.csv'
os.chdir(path)
main()

这时,在train和test的文件夹下分别出现train.csv 和test.csv。

4.csv to record

由于tensorflow无法识别csv文件,我们需要将csv转成record格式。

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

os.chdir('C:\\Users\\Kangaroo\\models\\research\\object_detection')     # 修改为object文件夹相对于此代码文件的路径
flags = tf.compat.v1.flags
flags.DEFINE_string('csv_input', '', 'Path to the CSV input')
flags.DEFINE_string('output_path', '', 'Path to output TFRecord')
FLAGS = flags.FLAGS

# 改为自己的分类个数
def class_text_to_int(row_label):
    if row_label == '1':
        return 1
    elif row_label == '2':
        return 2
    elif row_label == '3':
        return 3
    elif row_label == '4':
        return 4
    elif row_label == '5':
        return 5
    elif row_label == '6':
        return 6
    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.io.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(str(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.io.TFRecordWriter(FLAGS.output_path)
    # path = os.path.join(os.getcwd(), 'my_object/train')# 转换train写这句,代表train的图片集          
    path = os.path.join(os.getcwd(), 'my_object/test')   # 转换test写这句,代表test的图片集    
    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.compat.v1.app.run()

注意:

  • 修改为object文件夹相对于此代码文件的路径 ,就是让此代码运行时能找到xx_object文件夹,建议用绝对路径直接锁定object文件夹的位置
  • 修改成自己的分类,我的是6类
  • 修改对应的转换代码,具体我代码里有注明
  • 转换test时,路径给到object文件夹下test的图片集所在的位置
  • 转换train时,路径给到object文件夹下train的图片集所在的位置
  • 将此代码文件放在与xx_object文件夹同级别的目录下

这里,我把这个代码重命名为’ctt.py’,启动命令行,来到ctt所在的文件夹下输入

#转换test文件夹下使用
python ctt.py --csv_input=my_object/test/test.csv  --output_path=my_object/test/test.record
#转换train文件夹下使用
python ctt.py --csv_input=my_object/train/train.csv  --output_path=my_object/train/train.record

这时,在train和test的文件夹下分别出现train.record 和test.record。
在这里插入图片描述

小结

labelImg的操作是定制模型里最重复无聊但量大的工作。但这一步也直接关系到你生成模型的好坏,我们在选取训练照片时,尽量覆盖面广,比如亮光暗光下。你想想你如果遇上从没遇到过的题目是不是就无从下手了?计算机也是一样,况且计算机还不会像人一样思考,你没给他训练过这种情况,他在此情况下的识别率就会大大降低。
接下来就是配置训练文件,开始训练了。

2020年tensorflow定制训练模型笔记(1)——object detection的安装
2020年tensorflow定制训练模型笔记(2)——制作标签
2020年tensorflow定制训练模型笔记(3)——开始训练

  • 0
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 好的,下面是SparkSQL代码笔记03——连接Hive的中文回复: 在SparkSQL中,我们可以通过以下步骤连接Hive: 1. 首先,需要在SparkSession中启用Hive支持,可以使用以下代码: ``` from pyspark.sql import SparkSession spark = SparkSession.builder \ .appName("SparkSQL Hive Example") \ .config("spark.sql.warehouse.dir", "/user/hive/warehouse") \ .enableHiveSupport() \ .getOrCreate() ``` 其中,`enableHiveSupport()`方法启用了Hive支持,`config("spark.sql.warehouse.dir", "/user/hive/warehouse")`指定了Hive元数据存储的目录。 2. 接下来,我们可以使用`spark.sql()`方法执行Hive SQL语句,例如: ``` spark.sql("show databases").show() ``` 这将显示所有的Hive数据库。 3. 如果需要在SparkSQL中访问Hive表,可以使用以下代码: ``` df = spark.sql("select * from my_hive_table") ``` 其中,`my_hive_table`是Hive中的表名。 4. 如果需要在SparkSQL中创建Hive表,可以使用以下代码: ``` spark.sql("create table my_hive_table (id int, name string)") ``` 这将在Hive中创建一个名为`my_hive_table`的表,包含两个列:`id`和`name`。 以上就是连接Hive的基本步骤。需要注意的是,连接Hive需要在Spark集群中安装Hive,并且需要将Hive的JAR包添加到Spark的CLASSPATH中。 ### 回答2: SparkSQL是Apache Spark的一个组件,它提供了用于分布式数据处理的高级SQL查询引擎。SparkSQL支持连接多种数据源,其中之一就是Hive。 如何连接Hive? 在开始连接Hive之前,我们需要确保Hadoop和Hive的配置已经被正确的设置好了,以便Spark能够访问Hive元数据和数据。 首先,我们需要在Spark环境中添加Hive支持。运行下面的代码: `from pyspark.sql import SparkSession spark = SparkSession.builder \ .appName("hive_support") \ .enableHiveSupport() \ .getOrCreate()` 其中,`.enableHiveSupport()`将启用hive支持。 接下来,我们可以使用SparkSession连接Hive。运行下面的代码: `hive_df = spark.sql("SELECT * FROM default.student")` 其中,“default”是Hive的默认数据库,“student”是Hive数据库中的表名。 如果你要访问非默认的Hive数据库,可以使用下面的代码: `hive_df = spark.sql("SELECT * FROM dbname.student")` 其中,“dbname”是非默认的Hive数据库名。 我们还可以使用HiveContext来连接Hive。运行下面的代码: `from pyspark.sql import HiveContext hive_context = HiveContext(sc)` 其中,“sc”是SparkContext对象。 我们可以像这样从Hive中检索数据: `hive_df = hive_ctx.sql("SELECT * FROM default.student")` 现在你已经成功地连接Hive并从中检索了数据,你可以使用SparkSQL的强大功能对数据进行分析。而在连接Hive之外,在SparkSQL中还可以连接其他数据源,包括MySQL、PostgreSQL、Oracle等。 ### 回答3: Spark SQL是一个强大的分布式计算引擎,它可以支持处理多种数据源,并可通过Spark SQL shell、Spark应用程序或JDBC/ODBC接口等方式进行操作。其中,连接Hive是Spark SQL最常用的数据源之一。下面,将介绍如何通过Spark SQL连接Hive。 1、在Spark配置中设置Hive Support 要连接Hive,首先需要在Spark配置中开启Hive Support。在启动Spark Shell时,可以添加如下参数: ``` ./bin/spark-shell --master local \ --conf spark.sql.warehouse.dir="/user/hive/warehouse" \ --conf spark.sql.catalogImplementation=hive \ --conf spark.sql.hive.metastore.version=0.13 \ --conf spark.sql.hive.metastore.jars=maven ``` 这里以本地模式为例,设置Spark SQL的元数据存储在本地文件系统中,设置Hive为catalog实现,以及为Hive Metastore设置版本和JAR文件路径。根据实际情况,还可以指定其他参数,如Hive Metastore地址、数据库名称、用户名和密码等。 2、创建SparkSession对象 在连接Hive之前,需要先创建SparkSession对象。可以通过调用SparkSession.builder()静态方法来构建SparkSession对象,如下所示: ``` val spark = SparkSession.builder() .appName("SparkSQLTest") .config("spark.sql.warehouse.dir", "/user/hive/warehouse") .enableHiveSupport() .getOrCreate() ``` 这里通过builder()方法指定应用程序名称、元数据存储路径以及启用Hive Support,最后调用getOrCreate()方法创建SparkSession对象。 3、通过Spark SQL操作Hive表 通过Spark SQL连接Hive后,就可以通过Spark SQL语句来操作Hive表了。例如,我们可以使用select语句查询Hive表中的数据: ``` val df = spark.sql("SELECT * FROM tablename") df.show() ``` 其中,select语句指定要查询的列和表名,然后通过show()方法来显示查询结果。 除了查询数据之外,Spark SQL还可以通过insertInto语句将数据插入到Hive表中: ``` val data = Seq(("Alice", 25), ("Bob", 30)) val rdd = spark.sparkContext.parallelize(data) val df = rdd.toDF("name", "age") df.write.mode(SaveMode.Append).insertInto("tablename") ``` 这里先创建一个包含数据的RDD对象,然后将其转换为DataFrame对象,并指定列名。接着,通过insertInto()方法将DataFrame对象中的数据插入到Hive表中。 总之,通过Spark SQL连接Hive可以方便地查询、插入、更新和删除Hive表中的数据,从而实现更加灵活和高效的数据处理。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值