怎么用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++提取任意一张图片的特征(从内存读取数据),希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对我们网站的支持!

(0)

相关推荐

  • C++提取文件中信息的方法

    对于文件比较复杂的时候,为了获取文件中的信息,需要一些比较特殊的函数,比如,getline().replace().atoi,atof等 例子一,读取以下文件中的数据,并保存进一个类里面. 首先,类的定义如下,感觉是struct,但是按照struct的处理,我这段代码出错了,不知道什么问题,暂时po出来吧,有空看看. struct ImageLabel{ std::string imagePath;//save图片路径名 int faceBox[4];//输入点集的最外层包络矩形rect四个参数

  • 详解C++编程中的重载流插入运算符和流提取运算符

    C++的流插入运算符"<<"和流提取运算符">>"是C++在类库中提供的,所有C++编译系统都在类库中提供输入流类istream和输出流类ostream.cin和cout分别是istream类和ostream类的对象.在类库提供的头文件中已经对"<<"和">>"进行了重载,使之作为流插入运算符和流提取运算符,能用来输出和输入C++标准类型的数据.因此,凡是用"cout&

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

    关于使用C++接口来提取特征,caffe官方提供了一个extract_features.cpp的例程,但是这个文件的输入是blob数据,即使输入层使用的是ImageData,也需要在deploy.prototxt中指定图片的位置,很不方便. 如果想要使用opencv来读取一个图片,然后用caffe训练好的model提取特征,就需要对输入层进行改写.另外官方例程默认的输出是leveldb格式,我们也可以获取float类型的多维特征(数组),这样集成到我们的项目中更灵活. 01 首先我们需要改写de

  • Python从csv文件中读取数据及提取数据的方法

    目录 1.从csv文件中读取数据 2.数据切割 数据保存在csv文件中 1.从csv文件中读取数据 参数header=None的有无 (1)没有header=None--直接将csv表中的第一行当作表头 # 读取数据 import pandas as pd data = pd.read_csv("data1.csv") print(data) 打印结果为: (2)有header=None--自动添加第一行当作表头 # 读取数据 import pandas as pd data = pd

  • android提取视频多张图片和视频信息实例

    话说2016年的直播比较火,2017年短视频又火了.但对于开发者来说隐藏在这背后的技术才是我们所关心的,毕竟我们是靠技术吃饭的. 现在在安卓中多媒体服务比较强大,而与视频有关的视频基本处理技术有必要学习一下.我前段时间也在做有关视频的一些需求,当然也涉及本文的标题内容. 经测试和研究发现在android中提取视频图片的方法只有MediaMetadataRetriever这个类比较靠谱简单实用.当然OpenGL-也可以做到哈!(后者不展开介绍), 最后会把完整的demo献上. 效果图 技术需求 需

  • 5分钟内了解C语言的指针

    指针.引用和取值 什么是指针?什么是内存地址?什么叫做指针的取值?指针是一个存储计算机内存地址的变量.在这份教程里"引用"表示计算机内存地址.从指针指向的内存读取数据称作指针的取值.指针可以指向某些具体类型的变量地址,例如int.long和double.指针也可以是void类型.NULL指针和未初始化指针.本文会对上述所有指针类型进行探讨. 根据出现的位置不同,操作符 * 既可以用来声明一个指针变量,也可以用作指针的取值.当用在声明一个变量时,*表示这里声明了一个指针.其它情况用到*表

  • C++中volatile关键字及常见的误解总结

    前言 近期看到C++标准中对volatile关键字的定义,发现和java的volatile关键字完全不一样,C++的volatile对并发编程基本没有帮助.网上也看到很多关于volatile的误解,于是决定写这篇文章详细解释一下volatile的作用到底是什么. 为什么用volatile? C/C++ 中的 volatile 关键字和 const 对应,用来修饰变量,通常用于建立语言级别的 memory barrier.这是 BS 在 "The C++ Programming Language&

  • C++中volatile关键字的使用详解以及常见的误解

    为什么使用volatile ? C/C++中的 volatile 关键字 和const对应,用来修饰变量,通常用于建立语言级别的memory barrier.这是BS在"The C++ Programming Language"对volatile修饰词的解释: A volatile specifier is a hint to a compiler that an object may change its value in ways not specified by the lang

  • C++中const、volatile、mutable使用方法小结

    相信const大家对他并不陌生,可能大家在日常的编写代码当中就会时常用到const,但是剩下的两个关键字不知道我们有 没有使用过volatile和mutable两个关键字其实不算特别常用,但是我们一定要知道这个关键字有什么用,应该怎么用.首 先const的基本操作我曾经写过一篇博客:const的基本使用 现在我要说一个const操作里面比较骚的一些做法, 举个例子我们以前写过的一个类,我们会使用operator[]来返回一个reference的指向,这个一般情况我们都会写一个const的也会写一

  • C语言实现企业员工管理系统开发

    本文实例为大家分享了C语言实现企业员工管理系统的具体代码,供大家参考,具体内容如下 程序介绍 系统介绍 企业员工信息管理系统主要是对企业员工的基本信息进行增.删.改.查的相关操作,以便用户可以快速地对这些信息进行管理.本系统对管理者的控制更加严格,只设置一个管理账号. 操作流程 用户在编译完成后会产生一个系统的可执行文件,用户只要双击可执行文件就可以进入系统,如果是第一次进入系统,首先要对系统进行初始化,如图所示,初始化完成后,再次双击系统执行文件,进入如图的界面. 用户在输入正确密码后,进入系

  • C++之list容器介绍及使用方式

    目录 一.list底层结构 二.构造方法 构造函数 拷贝构造函数 三.元素访问和迭代器 back&front 三种遍历方式 四.元素修改 尾插.头插.尾删.头删 insert.erase swap resize 五.特殊操作 remove remove_if unique.sort reverse 六.list迭代器失效问题 七.vector与list对比 总结 一.list底层结构 list底层是带头节点的双向循环链表 双向:可以从前往后,也可以从后往前遍历 循环:找尾节点的时间复杂度为O(

  • python ffmpeg任意提取视频帧的方法

     环境准备 1.安装 FFmpeg 音/视频工具 FFmpeg 简易安装文档 2.安装 ffmpeg-python pip3 install ffmpeg-python 3.[可选]安装 opencv-python pip3 install opencv-python 4.[可选]安装 numpy pip3 install numpy 视频帧提取 准备视频素材 抖音视频素材下载:https://anoyi.com/dy/top 基于视频帧数提取任意一帧 import ffmpeg import

随机推荐