20.opencv的DNN模块
DNN 深度神经网络这个是读模型的,像我现在用的模型是caffe训练出来的,所以用这个它也有别的框架的接口,比如我们现在看readNetFromCaffe()第一个参数是神经网络配置文件,第二个参数是训练好的模型1代码分析项目由两个py文件组成,一个是bolb_from_images.py这个是主函数,另一个是utils_paths.py这个py文件会在主函数中调用utils_paths只在bol
- DNN 深度神经网络
这个是读模型的,像我现在用的模型是caffe训练出来的,所以用这个
它也有别的框架的接口,比如
我们现在看readNetFromCaffe()
第一个参数是神经网络配置文件,第二个参数是训练好的模型
目录
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获取目录中的 路径,文件夹,文件,之后进行遍历
- os.walk()在这里有介绍 其余python常见操作_potato123232的博客-CSDN博客
之后遍历所有文件
如果传入进来的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,导入这个库的速度是非常慢的
更多推荐
所有评论(0)