• DNN 深度神经网络

这个是读模型的,像我现在用的模型是caffe训练出来的,所以用这个

它也有别的框架的接口,比如

我们现在看readNetFromCaffe()

第一个参数是神经网络配置文件,第二个参数是训练好的模型

目录

1  代码分析

1.1  utils_paths.py

1.1.1  导入库

1.1.2  定义一个元组

1.1.3  定义list_images()

1.1.4  定义 list_files()

1.2  bolb_from_images.py

1.2.1  导入库

1.2.2  标签文件处理

1.2.3  读模型概览与模型

1.2.4  读取图像路径

1.2.5  图像预处理

1.2.6  输入图像

1.2.7  得到预测结果

1.2.8  处理预测结果

1.2.9  显示预测结果

1.2.10  预测区域图


1  代码分析

项目由两个py文件组成,一个是bolb_from_images.py这个是主函数,另一个是utils_paths.py这个py文件会在主函数中调用

utils_paths只在bolb_from_images.py调用了一次,我们先看一下utils_paths.py


1.1  utils_paths.py

1.1.1  导入库

1.1.2  定义一个元组

这个元组中的内容全部是图像的尾缀

1.1.3  定义list_images()

list_iamges()只有传递变量的功能

执行后直接把basePath,validExts(上面创建的元组),contains传递给list_files()


1.1.4  定义 list_files()

进入函数后,首先使用os.walk获取目录中的 路径,文件夹,文件,之后进行遍历

之后遍历所有文件

如果传入进来的contains不是None,并且该文件名中找不到contains的内容,则跳出这个小循环

我们再向下看,我们在文件名中提取点之后的内容(尾缀),然后给它变成小写,之后赋值给ext

如果validExts不是None,这个如果调用了list_images进入的就不是None,如果是直接调用的list_files就是None,或者刚刚提取的尾缀不是以validExts中的内容结尾(这一步是确定filename是图片类型的文件)

如果前面的两个条件都满足,那么讲rootDir与filename组合到一起(imagePath是绝对路径),然后返回可迭代的imagePath

1.2  bolb_from_images.py


1.2.1  导入库

1.2.2  标签文件处理

synset_words.txt是我们训练模型的标签,我们打开看一下

下面还有我就不都展示了,只要是里面有的东西,我们就可以识别出来

使用open().read()可以得到txt中所有的字符串,strip是删除字符串两端的空格,split('\n')是提取每一行的内容,现在我们的rows是一个列表,内容是synset_words.txt中每一行的内容

之后对每一行的内容进行遍历,遍历之后找每一行的空格(r.find(' '))

像是这一行的这个位置

找到位置后让位置+1,然后r提取到+1的位置一直到最后,也就是这一行我们现在只剩下这里了

之后以所有逗号为分隔符然后删除他们,取分割的第一个值,像下面这一行,我们现在只剩tench这个字符串了

提取完之后赋值给classes,现在我们class是这样的,会提取出每行第一个空格后的字符串

1.2.3  读模型概览与模型

我们打开bvic_googlenet.prototext看一下

和tensorflow中的model.summary()相似,有输出有输入还有每一层的情况

1.2.4  读取图像路径

在这里用到了utils_paths.py中的list_images(),这个在上面介绍过,是提取images这个文件夹中所有图片的绝对路径,然后讲所有绝对路径作为元素组成迭代器

我们看一下ImagePaths的内容

过滤掉了一个py文件,那个py文件的路径不会出现在imagePaths中

之后又使用sorted()排了个序,这个是字符串之间的排序,先比首字母,再比第二个字母,都相同时比长度


1.2.5  图像预处理

先读取第0张图片,然后把它的尺寸变为(224,224)

这个是因为我们模型的输入是224*224

之后我们使用blobFromImage()改变图像的大小,然后令R,G,B三个通道分别减去均值

  • 减均值的目的是去除光照对结果的影响

blobFromImage()的参数为

  • resized 要改变的图像
  • 1 缩放系数,我们当前用的时1,所以不变
  • (224,224) 图像大小
  • (104,117,123) 图像三通道均值,我们用的网络叫Imagenet,这三个均值是Imagenet提供的

改变之后我们看一下blob的shape

第一个值的意思是图片数量,第二个值是图片通道数,第三个值是宽,第四个值是高

根据模型的不同我们预处理的方式也不同,所有的预处理都是为了迎合模型,当前我们现在有了这一张四维的图像作为输入图像


1.2.6  输入图像

1.2.7  得到预测结果

我们的Imagenet是一个千分类模型,它会有1000个值对应1000个分类的概率,我们打印出其长度与本身看一下

1.2.8  处理预测结果

我们首先找出这些值中最大的值

这里我们用到了np.argsort(),我们举个例子

import numpy as np
a = [0.7,0.54,0.9,-1]
b = np.argsort(a)
print(b)

上面这个列表的意思是 3号位的这个值最小(-1),其次是1号位(0.54),再其次是0号位(0.7),再其次是2号位(0.9)

由于np.argsort()是从小到大进行排序,所以我们现在要将其逆序([::-1]),逆序之后选取第一个值(最大值的索引)

找到最大值索引之后,我们向classes中获取该索引的标签,然后把pred[0]中的值乘以100保留两位小数后面再加个百分号作为要写的内容

之后将要写的内容写在未经处理的图片上

image是我们图片中的第一张图

1.2.9  显示预测结果

1.2.10  预测区域图

下面我们一起预测其余的所有图,方法与上面相似,我们简单带过

先定义一个空列表存图

处理除第0张外的所有图片

上面的功能为blobFromImages()是用来处理多张图像的,上面处理单张图像的功能为blobFromImage()

  • 对上面单张图像处理直接用循环更省事,但是可能运算速度会慢些

预测

此时的preds中有四个图像的预测结果

之后标个序号并排列所有图,i是序号,p是图片路径

首先读进来图,之后找到对应预测结果中最大的,然后写上标签与概率,之后展示出来

我们也可以直接使用训练对应的人工智能框架进行预测,我们上面提到的这种方法是只需要安装opencv以及训练的相关文件的,这个在嵌入式的开发中还是很受用的,比如说我要在树莓派中运行tensorflow的训练模型,我就不用在树莓派中导入tensorflow,导入这个库的速度是非常慢的

Logo

技术共进,成长同行——讯飞AI开发者社区

更多推荐