0x00

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

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

0x01

首先我们需要改写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不影响。

0x02

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

0x03

下面是更改之后的 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;
}

caffe:使用C++来提取任意一张图片的特征的更多相关文章

  1. caffe:使用C++来提取任意一张图片的特征(从内存读取数据)

    0x00 关于使用C++接口来提取特征,caffe官方提供了一个extract_features.cpp的例程,但是这个文件的输入是blob数据,即使输入层使用的是ImageData,也需要在depl ...

  2. Caffe C++API 提取任意一张图片的特征系列二----MemoryData

    介绍一种更加灵活的方法,用MemoryData层输入数据,可以直接用opencv接口读入我们的图片再添加的网络中.  第一个问题:仍然是工程建立问题,提示卷积层或其他层没有注册,解决方法与上一篇博客一 ...

  3. Caffe提取任意层特征并进行可视化

    现在Caffe的Matlab接口 (matcaffe3) 和python接口都非常强大, 可以直接提取任意层的feature map以及parameters, 所以本文仅仅作为参考, 更多最新的信息请 ...

  4. OpenCV提取显示一张图片(或者视频)的R,G,B颜色分量

    使用OpenCV可以提分别提取显示一张图片(或者视频)的R,G,B颜色分量.效果如下. 原图: R: G: B: 示例代码如下,貌似很久以前网上找的的,逻辑很清晰,就是把R,G,B三个分量分开,然后显 ...

  5. caffe的python接口提取resnet101某层特征

    论文的caffemodel转化为tensorflow模型过程中越坑无数,最后索性直接用caffe提特征. caffe提取倒数第二层,pool5的输出,fc1000层的输入,2048维的特征 #codi ...

  6. caffe matlab 借口怎么提取灰度图的 feature ? What happened if I mixed the color images with gray images together for training ?

    1. caffe matlab 接口提供了提取feature的脚本,但是由于中间要对这些图像进行RGB ---> BGR 的变换,卧槽,灰度图没有三通道啊?怎么破?从上午就在纠结怎么会跑着跑着程 ...

  7. 学习笔记之 初试Caffe,Matlab接口提取feature

    Caffe 提供了matlab接口,可以用于提取图像的feature.

  8. caffe提取每一层中的特征,在matlab或python查看

    参考博客: http://blog.csdn.net/abc8730866/article/details/52522843 http://blog.csdn.net/lijiancheng0614/ ...

  9. Machine Learning With Spark学习笔记(提取10万电影数据特征)

    注:原文中的代码是在spark-shell中编写运行的,本人的是在eclipse中编写运行,所以结果输出形式可能会与这本书中的不太一样. 首先将用户数据u.data读入SparkContext中.然后 ...

随机推荐

  1. jQuery Validate前端验证

    我们经常看到如下效果,那么它是如何实现的呢?看下面: 废话少说,直接上代码,大家直接Copy就能看到上面的效果啦. <html> <head> <title>验证内 ...

  2. 使用DbVisualizer变量

    变量可用于构建参数化SQL语句,并让DbVisualizer在执行SQL时提示您输入值.如果您重复执行相同的SQL,只是希望在同一个SQL语句中传递新数据,这很方便. 变量语法 变量格式支持设置默认值 ...

  3. MySQL结构相关

    MySQL 由以下几部分组成: 1.Connectors指的是不同语言中与SQL的交互 2.Management Serveices & Utilities: 系统管理和控制工具 3.Conn ...

  4. root密码忘记怎么办?

    忘记root密码:按 e进入内核在按e,后面加1 .按b启动 进入命令行输入passwd,设置新的密码后exit退出即可

  5. PostgreSQL 满足条件时插入数据

    例如:当表中不存在某记录时,才插入这条记录. INSERT INTO 表名(列名1, 列名2) SELECT '值1', '值2' WHERE NOT EXISTS ( SELECT * FROM 表 ...

  6. poj 2955 Brackets 【 区间dp 】

    话说这题自己折腾好久还是没有推出转移的公式来啊------------------ 只想出了dp[i][j]表示i到j的最大括号匹配的数目--ค(TㅅT)------------------- 后来搜 ...

  7. Swift 中实现 Promise 模式

    在异步编程中,除了竟态处理.资源利用以外,另外一个难点就是流程管理.在拥有匿名函数.闭包这些特性的编程语言中,我们通常可以使用回调函数来做一个异步任务完成或失败时的处理.但当我们的业务逻辑逐渐复杂时, ...

  8. The features of Swift

    The features of Swift are designed to work together to create a language that is powerful, yet fun t ...

  9. 应用二:Vue之ElementUI Form表单校验

    (注:本文适用于有一定Vue基础或开发经验的读者,文章就知识点的讲解不一定全面,但却是开发过程中很实用的)   表单校验是前端开发过程中最常用到的功能之一,根据个人的工作经验总结在此对表单校验功能的基 ...

  10. Spring cloud服务的提供者建立

    1.0我们要在这里要建立一个服务的提供者模块,是一个module,类似于服务的公共模块 第一步:添加架包 <project xmlns="http://maven.apache.org ...