七月 上海| 高性能计算之GPU CUDA培训

7月27-29日三天密集式学习  快速带你入门阅读全文>

正文共2073个字,2张图,预计阅读时间10分钟。

一、初得模型

那是一个月之前的事情了,我利用TesorFlow Object Detection API训练了现在目标检测里面应该是最快的网络MobileNet。当时的目的就只是学习整个finetuning的流程,于是我只是用了20张自己标注的人脸样本图片作为训练集去finetuning,训练完之后的模型通过修改TesorFlow Object Detection API自带的例程代码,即object_detection_tutorial.ipynb,运行结果竟然还不错,对于图片中的大小适中的人脸能够比较准确地检测,毕竟我只用了20个样本训练啊。当然,了解了流程和方法之后,以后多少样本的训练都不在话下......只要有足够数据和够好的显卡...

tensorflow自带例子加载检测结果

二、C++调用之难,难于上西天

然而,其实我训练的目标检测模型是要在C++环境下用的。TensorFlow也提供了C++ API,但是要用的话需要自己从源码编译,而且用的是Bazel。是的,我用的是Windows,所以,在尝试安装BazelN次失败之后,我尝试用OpenCV3.3.0新出的dnn模块调用训练好的模型。然而新出的dnn模块当时支持的模型太少了,它支持ssd-mobilenet的caffe模型,但是并不支持mobilenet的tensorflow模型,当时也看到了github上有人提交issue提到这个问题。

问题的issue参考这里:Unable to import mobilenet model using latest OpenCV.#9462。

有人在这里给出了一个解决方案:Layers for MobileNet from TensorFlow #9517。

解决方案里面最后一步:Modify for DNN: fuse batch normalizations and removeSqueezeop.需要用到一个工具:transform_graph。而这个工具需要用bazel编译......又回到了bazel......

三、柳暗花明

在没能力自己修复问题之前,只能等待大神解决。一个月期间,多次尝试bazel,包括windows环境和ubuntu环境,可能对这些工具不熟悉吧,总之没能成功解决。终于盼到十月份OpenCV3.3.1出来,果然对此有了更新。而且加载模型的API也有了变化,从原来的一个参数变成了两个参数。而且针对MobileNet还给出了一种解决方案。目前尚不能确定这种方案是否适用于其他模型,比如Inception等。

现在把这种方法记录如下,以备后用,以防遗忘,同时帮助同道中人。

  • 首先通过TensorFlow detection_model_zoo下载他们训练好的模型,或者用TesorFlow Object Detection API训练或者finetuning之后,由models-master\object_detection\export_inference_graph.py导出的模型文件frozen_inference_graph.pb。(利用object_detection_tutorial.ipynb的话,只是这一个文件就够了。)

  • 到https://github.com/opencv/opencv_extra/blob/master/testdata/dnn/ssd_mobilenet_v1_coco.pbtxt)下载ssd_mobilenet_v1_coco.pbtxt。然后把这个文件的第2222行修改为attr { key: "num_classes" value { i: 2 } }。其中这个2根据自己的需要改成目标数+1。比如我这里只有一类——人脸,所以我改为2。

  • 参考mobilenet_ssd_python.py,这个文件在这里https://github.com/opencv/opencv/blob/master/samples/dnn/mobilenet_ssd_python.py。

  • 还有一点,要用最新的OpenCV3.3.1,OpenCV3.3.0是不行的。

这里的例子mobilenet_ssd_python.py是Python的,我结合OpenCV给出的例子ssd_mobilenet_object_detection.cpp,修改了一个C++的版本,其实都差不多。例子很多,而且代码很相似,所以木有注释。如下:

 1#include<opencv2\opencv.hpp> 2#include<opencv2\dnn.hpp> 3#include <iostream> 4using namespace std; 5using namespace cv; 6const size_t inWidth = 300; 7const size_t inHeight = 300; 8const float WHRatio = inWidth / (float)inHeight; 9const char* classNames[] = { "background","face" };10int main() {11String weights = "face_frozen_inference_graph.pb";12String prototxt = "ssd_mobilenet_v1_coco.pbtxt";13dnn::Net net = cv::dnn::readNetFromTensorflow(weights, prototxt);14Mat frame = cv::imread("image4.jpg");15Size frame_size = frame.size();16Size cropSize;17if (frame_size.width / (float)frame_size.height > WHRatio)18{19cropSize = Size(static_cast<int>(frame_size.height * WHRatio),20    frame_size.height);21}22else23{24cropSize = Size(frame_size.width,25    static_cast<int>(frame_size.width / WHRatio));26}27Rect crop(Point((frame_size.width - cropSize.width) / 2,28(frame_size.height - cropSize.height) / 2),29cropSize);30cv::Mat blob = cv::dnn::blobFromImage(frame,1./255,Size(300,300));31//cout << "blob size: " << blob.size << endl;32net.setInput(blob);33Mat output = net.forward();34//cout << "output size: " << output.size << endl;35Mat detectionMat(output.size[2], output.size[3], CV_32F, output.ptr<float>());36frame = frame(crop);37float confidenceThreshold = 0.20;38for (int i = 0; i < detectionMat.rows; i++)39{40float confidence = detectionMat.at<float>(i, 2);4142if (confidence > confidenceThreshold)43{44    size_t objectClass = (size_t)(detectionMat.at<float>(i, 1));4546    int xLeftBottom = static_cast<int>(detectionMat.at<float>(i, 3) * frame.cols);47    int yLeftBottom = static_cast<int>(detectionMat.at<float>(i, 4) * frame.rows);48    int xRightTop = static_cast<int>(detectionMat.at<float>(i, 5) * frame.cols);49    int yRightTop = static_cast<int>(detectionMat.at<float>(i, 6) * frame.rows);5051    ostringstream ss;52    ss << confidence;53    String conf(ss.str());5455    Rect object((int)xLeftBottom, (int)yLeftBottom,56        (int)(xRightTop - xLeftBottom),57        (int)(yRightTop - yLeftBottom));5859    rectangle(frame, object, Scalar(0, 255, 0),2);60    String label = String(classNames[objectClass]) + ": " + conf;61    int baseLine = 0;62    Size labelSize = getTextSize(label, FONT_HERSHEY_SIMPLEX, 0.5, 1, &baseLine);63    rectangle(frame, Rect(Point(xLeftBottom, yLeftBottom - labelSize.height),64        Size(labelSize.width, labelSize.height + baseLine)),65        Scalar(0, 255, 0), CV_FILLED);66    putText(frame, label, Point(xLeftBottom, yLeftBottom),67        FONT_HERSHEY_SIMPLEX, 0.5, Scalar(0, 0, 0));68}69}70namedWindow("image", CV_WINDOW_NORMAL);71imshow("image", frame);72waitKey(0);73return 0;74}

最后的测试结果如下:

OpenCV dnn模块加载检测结果

四、路漫漫

对比两种方式的检测结果,我觉得还是tensorflow的方框更精确一点,而且后者的图片是裁剪过的。另外,两种结果的confidence不一样,估计是实现的方式不太一样。这一点还需要继续探究,今天先把方法记下来。同时欢迎大家指点,集思广益。

原文链接:https://www.jianshu.com/p/4f58029ceece

查阅更为简洁方便的分类文章以及最新的课程、产品信息,请移步至全新呈现的“LeadAI学院官网”:

www.leadai.org

请关注人工智能LeadAI公众号,查看更多专业文章

大家都在看

LSTM模型在问答系统中的应用

基于TensorFlow的神经网络解决用户流失概览问题

最全常见算法工程师面试题目整理(一)

最全常见算法工程师面试题目整理(二)

TensorFlow从1到2 | 第三章 深度学习革命的开端:卷积神经网络

装饰器 | Python高级编程

今天不如来复习下Python基础

OpenCV的dnn模块调用TesorFlow训练的MoblieNet模型相关推荐

  1. 使用opencv dnn 模块调用darknet模型时候出错,不支持relu激活函数

    问题: 使用opencv dnn 模块调用darknet模型时候出错,报错信息为 不支持relu激活函数 以下过程为笔者自己解决该问题的过程,供各位参考学些,因为中间又遇到新的坑,所以各位务必看完再决 ...

  2. 用opencv的dnn模块做yolov5目标检测

    最近在微信公众号里看到多篇讲解yolov5在openvino部署做目标检测文章,但是没看到过用opencv的dnn模块做yolov5目标检测的.于是,我就想着编写一套用opencv的dnn模块做yol ...

  3. OpenCV之DNN模块,实现深度学习网络的推理加速

    OpenCV是计算机视觉领域使用最为广泛的开源库,以功能全面使用方便著称.自3.3版本开始,OpenCV加入了对深度神经网络(DNN)推理运算的支持.在LiveVideoStack线上交流分享中英特尔 ...

  4. AI入门之神经网络(9)基于c++、opencv的dnn模块的视频手势识别

    基于c++.opencv的dnn模块的手势识别 先看效果: 老规矩话不多,实现的方法步骤,细节全在我的代码注释里面,只你跟着注释写,相信你也写得出来的! #include <opencv2/dn ...

  5. 如何调用 caffe 训练好的模型对输入图片进行测试

    如何调用 caffe 训练好的模型对输入图片进行测试 该部分包括两篇文章 win10 下 caffe 的第一个测试程序(附带详细讲解) 主要讲解如何利用 caffe 来训练模型. 如何调用 caffe ...

  6. opencv3.4.3的DNN模块调用bvlc_googlenet.caffemodel实现图像分类

    DNN模块官方文档:https://docs.opencv.org/3.4.3/d6/d0f/group__dnn.html#ga29d0ea5e52b1d1a6c2681e3f7d68473a 1. ...

  7. opencv调用自己训练的yolo3模型

    一 实现流程 1.准备好自己的数据集,通过yolo3结构框架训练好自己的模型文件(loss值一般训练到10就OK)yolov3源码:https://github.com/qqwweee/keras-y ...

  8. 使用OpenCV调用Caffe-SSD训练好的模型

    前言 1.OpenCV3之后的dnn模型可以可以调用好多用深度学习框架的训练好的模型. 2.这里我演示是我自己训练的一个围棋棋盘识别模型,使用的神经网络是VGG16,OpenCV3.3,IDE是VS2 ...

  9. 调用lssvm训练好的模型

    最近要实现异步电机的LSSVM逆控制,参考文献<基于LS-SVM的异步电机解耦控制方法>已附.遇到的问题是:训练得到的模型model挺好的,为什么单独拿出来调用,效果却很差?我的程序贴出来 ...

最新文章

  1. Android 监听 Android中监听系统网络连接打开或者关闭的实现代码
  2. for、for / in循环
  3. X3D.Studio编辑器界面介绍
  4. linux 服务端口查询,linux 怎么查看服务和端口
  5. __name__ == '__main__'的用法
  6. 【Kafka】kafka SSL close message 远程主机被迫关闭了一个连接
  7. java.lang.VerifyError: Expecting a stack map frame
  8. MySQL8增量备份1008无标题_mysql增量备份
  9. #python 颜色聚类处理
  10. 【毕设教程】如何使用单片机控制步进电机
  11. word选择粘贴没有html格式,Word选择性粘贴怎么用?Word设置无格式文本粘贴快捷键的方法...
  12. Battery (Coin Change)
  13. 2005。1。22,闹洞房安排。
  14. 【数学】扩展卢卡斯定理
  15. 聊聊信任:衣服掉地上会脏的
  16. 刘兵《Entity and aspect extraction for opinion mining 》翻译笔记
  17. 程序员:必备技能 Git
  18. Knativa 基于流量的灰度发布和自动弹性实践
  19. 领英发布2019年职场十大趋势 新一线城市吸引力增强
  20. JavaWebDay11_BootStrap概述,快速入门,常用样式组件插件

热门文章

  1. 租赁笔记本电脑哪里有_广东哪里有离心鼓风机优势-长沙鼓风机厂
  2. 【script】python3使用http.server搭建简易web服务
  3. oracle打开文件模式无效,oracle expdp导入时 提示“ORA-39002: 操作无效 ORA-39070: 无法打开日志文件 ”...
  4. vue读取终端硬件信息_自助服务终端机主要特点及规格
  5. FW: How to use Hibernate Lazy Fetch and Eager Fetch Type – Spring Boot + MySQL
  6. Centos下安装Gcc和Qt
  7. 解决在Windows10没有修改hosts文件权限
  8. mysql常用命令整理
  9. Public key for mysql....rpm is not installed
  10. sed for windows 双引号内部内容的替换