怎么用C++提取任意一张图片的特征(从内存读取数据)

 更新时间:2017年05月02日 10:56:53   作者:WHLOOK  
这篇文章主要介绍了用C++提取任意一张图片的特征(从内存读取数据)的相关资料,需要的朋友可以参考下

  关于使用C++接口来提取特征,caffe官方提供了一个extract_features.cpp的例程,但是这个文件的输入是blob数据,即使输入层使用的是ImageData,也需要在deploy.prototxt中指定图片的位置,很不方便。

如果想要使用opencv来读取一个图片,然后用caffe训练好的model提取特征,就需要对输入层进行改写。另外官方例程默认的输出是leveldb格式,我们也可以获取float类型的多维特征(数组),这样集成到我们的项目中更灵活。

01

  首先我们需要改写deploy.prototxt的输入层为"MemoryData":

layer {
 name: "data"
 type: "MemoryData"
 top: "data"
 top: "label"
 memory_data_param{
 batch_size:1
 channels:3
 height:100
 width:100
 }
}

  在之前的训练中可能使用的是"ImageData"、"Data"之类的,现在改成MemoryData不影响。

02

  我准备提取的层的名字是"res5_6",就是"InnerProduct"的前一层,当我想提取"InnerProduct"全连接层的输出时,总是报错,提示原始参数和网络参数不匹配(就是训练好的model和现在deploy的网络维度不一样),所以只好提取前一层了,并且要把全连接层屏蔽掉,屏蔽的方法是把prototxt里相应层的名字改掉就好(相对于caffemodel里面的名字)。[以上问题暂时还没解决,留坑]

03

  下面是更改之后的 extract_features.cpp的代码:

#include <stdio.h> 
#include <string>
#include <vector>
#include <iostream>
#include <opencv2/opencv.hpp>
#include "boost/algorithm/string.hpp"
#include "google/protobuf/text_format.h"
#include "caffe/blob.hpp"
#include "caffe/common.hpp"
#include "caffe/net.hpp"
#include "caffe/proto/caffe.pb.h"
#include "caffe/util/io.hpp"
#include "caffe/layers/memory_data_layer.hpp"
#define NetTy float 
using namespace caffe;
using std::cout;
using std::endl;
using std::string;
/* 加载模型函数 */
template <typename Dtype>
caffe::Net<Dtype>* loadNet(std::string param_file, std::string pretrained_param_file, caffe::Phase phase)
{
 caffe::Net<Dtype>* net(new caffe::Net<Dtype>(param_file, phase));
 net->CopyTrainedLayersFrom(pretrained_param_file);
 return net;
}
int main()
{
 cv::Mat src;
 src = cv::imread("face_example/test.jpg"); // 读取测试图片
 cv::resize(src, src, cv::Size(100, 100)); // 这里要将图片resize到prototxt里面的输入层指定的大小
 caffe::Net<NetTy>* _net = loadNet<NetTy>("face_example/face_deploy.prototxt", "face_example/face.caffemodel", caffe::TEST); // 加载网络定义文件和参数模型
 caffe::MemoryDataLayer<NetTy> *m_layer = (caffe::MemoryDataLayer<NetTy> *)_net->layers()[0].get(); // 定义个内存数据层指针
 std::vector<cv::Mat> dv = { src }; // AddMatVector(const vector<cv::Mat>& mat_vector,const vector<int>& labels)
 std::vector<int> label = { 0 }; // -------------------------------------------------------------------------
 m_layer->AddMatVector(dv, label); // 把图片和标签,添加到 MemoryData层
 std::vector<caffe::Blob<NetTy>*> input_vec; // 无意义,为了函数参数需要
 _net->Forward(input_vec);     // 执行一次前向计算
 boost::shared_ptr<caffe::Blob<NetTy>> layerData = _net->blob_by_name("res5_6"); // 获得指定层的输出
 const NetTy* pstart = layerData->cpu_data(); // res5_6->cpu_data()返回的是多维数据(数组)
 /*-----输出特征-----*/
 for (int i = 0; i < 30000; i++)
 {
  std::cout << *pstart << endl;
  pstart++;
 }
 return 0;
}

以上所述是小编给大家介绍的怎么用C++提取任意一张图片的特征(从内存读取数据),希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对脚本之家网站的支持!

相关文章

  • linux c模拟ls命令详解

    linux c模拟ls命令详解

    本篇文章是对linux中基于c模拟ls命令的实现方法进行了详细的分析介绍,需要的朋友参考下
    2013-06-06
  • C语言报错:Undefined Reference的产生原因和解决方案

    C语言报错:Undefined Reference的产生原因和解决方案

    Undefined Reference(未定义引用)是C语言编译过程中常见的错误之一,通常在链接阶段出现,本文将详细介绍Undefined Reference的产生原因,提供多种解决方案,并通过实例代码演示如何有效避免和解决此类错误,需要的朋友可以参考下
    2024-06-06
  • 在Visual Studio使用C++开发Metro应用

    在Visual Studio使用C++开发Metro应用

    这篇文章主要介绍了在Visual Studio使用C++开发Metro应用的示例,尽管只是一个Hello world,但可以体现出VS下为开发者提供的方便,需要的朋友可以参考下
    2015-07-07
  • C++使用MySQL-Connector/C++连接MySQL出现LNK2019错误的解决方法

    C++使用MySQL-Connector/C++连接MySQL出现LNK2019错误的解决方法

    这篇文章主要介绍了C++使用MySQL-Connector/C++连接MySQL出现LNK2019错误的解决方法,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2018-03-03
  • C语言三个数排列大小的实现方法

    C语言三个数排列大小的实现方法

    下面小编就为大家带来一篇C语言三个数排列大小的实现方法。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-06-06
  • C++深入探究继承的概念与使用

    C++深入探究继承的概念与使用

    继承是C++面向对象编程中的一门。继承是子类继承父类的特征和行为,或者是继承父类得方法,使的子类具有父类得的特性和行为。重写是子类对父类的允许访问的方法实行的过程进行重新编写,返回值和形参都不能改变。就是对原本的父类进行重新编写,但是外部接口不能被重写
    2022-05-05
  • C语言实例之双向链表增删改查

    C语言实例之双向链表增删改查

    双向链表(Doubly Linked List)是一种常见的数据结构,在单链表的基础上增加了向前遍历的功能,与单向链表不同,双向链表的每个节点除了包含指向下一个节点的指针外,还包含指向前一个节点的指针,本文给大家介绍了C语言中双向链表的增删改查
    2023-08-08
  • 基于C语言实现五子棋游戏完整实例代码

    基于C语言实现五子棋游戏完整实例代码

    这篇文章主要介绍了基于C语言实现五子棋游戏完整实例代码,相信对于学习游戏开发的朋友会有一定的帮助与借鉴价值,需要的朋友可以参考下
    2014-08-08
  • C语言实现俄罗斯方块源代码

    C语言实现俄罗斯方块源代码

    这篇文章主要为大家详细介绍了C语言实现俄罗斯方块的源代码,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2018-06-06
  • C++模拟实现string的示例代码

    C++模拟实现string的示例代码

    这篇文章主要为大家详细介绍了C++模拟实现string的相关资料,文中的示例代码讲解详细,对我们学习C++有一定的帮助,需要的可以参考一下
    2022-11-11

最新评论