功能:

计算训练数据库的平均图像。

由于平均归一化训练图像会对结果有提升,所以Caffe里面,提供了一个可选项。

用法:

compute_image_mean [FLAGS] INPUT_DB [OUTPUT_FILE]\n”)

參数:INPUT_DB: 数据库

參数(可选):OUTPUT_FILE: 输出文件名称,不提供的话,不保存平均图像blob

实现方法:

数据源:求平均图像的方法是直接从数据库(LevelDB或者LMDB)里面直接读取出来的,而不是直接用图像数据库里面求出,意味着,必须先进行图像到数据库的转换后,才干求平均图像这一步。

接下来就是遍历KV数据库的每个值while (cursor->valid()) 将每个数据值转换为Datum,datum.ParseFromString(cursor->value());

接着将Datum阶码到sum_blob 中。sum_blob 是一个num=1,channels=图像.channel,height=图像.height ,width=图像.width 的blob

累加:

sum_blob.set_data(i, sum_blob.data(i) + (uint8_t)data[i]);

最后求平均:

sum_blob.set_data(i, sum_blob.data(i) / count);

存在的问题:上述代码仅仅是先累加在处于数目求和,显然,假设须要求平均的图像的数目相当多的话,就有可能溢出(浮点溢出)。

最后,假设要求简单一点的话,也能够直接求每个通道的平均值。

源码://2015.06.04版本号

#include <stdint.h>
#include <algorithm>
#include <string>
#include <utility>
#include <vector> #include "boost/scoped_ptr.hpp"
#include "gflags/gflags.h"
#include "glog/logging.h" #include "caffe/proto/caffe.pb.h"
#include "caffe/util/db.hpp"
#include "caffe/util/io.hpp" using namespace caffe; // NOLINT(build/namespaces) using std::max;
using std::pair;
using boost::scoped_ptr; DEFINE_string(backend, "lmdb",
"The backend {leveldb, lmdb} containing the images"); int main(int argc, char** argv) {
::google::InitGoogleLogging(argv[0]); #ifndef GFLAGS_GFLAGS_H_
namespace gflags = google;
#endif gflags::SetUsageMessage("Compute the mean_image of a set of images given by"
" a leveldb/lmdb\n"
"Usage:\n"
" compute_image_mean [FLAGS] INPUT_DB [OUTPUT_FILE]\n"); gflags::ParseCommandLineFlags(&argc, &argv, true); if (argc < 2 || argc > 3) {
gflags::ShowUsageWithFlagsRestrict(argv[0], "tools/compute_image_mean");
return 1;
} scoped_ptr<db::DB> db(db::GetDB(FLAGS_backend));
db->Open(argv[1], db::READ);
scoped_ptr<db::Cursor> cursor(db->NewCursor()); BlobProto sum_blob;
int count = 0;
// load first datum
Datum datum;
datum.ParseFromString(cursor->value()); if (DecodeDatumNative(&datum)) {
LOG(INFO) << "Decoding Datum";
} sum_blob.set_num(1);
sum_blob.set_channels(datum.channels());
sum_blob.set_height(datum.height());
sum_blob.set_width(datum.width());
const int data_size = datum.channels() * datum.height() * datum.width();
int size_in_datum = std::max<int>(datum.data().size(),
datum.float_data_size());
for (int i = 0; i < size_in_datum; ++i) {
sum_blob.add_data(0.);
}
LOG(INFO) << "Starting Iteration";
while (cursor->valid()) {
Datum datum;
datum.ParseFromString(cursor->value());
DecodeDatumNative(&datum); const std::string& data = datum.data();
size_in_datum = std::max<int>(datum.data().size(),
datum.float_data_size());
CHECK_EQ(size_in_datum, data_size) << "Incorrect data field size " <<
size_in_datum;
if (data.size() != 0) {
CHECK_EQ(data.size(), size_in_datum);
for (int i = 0; i < size_in_datum; ++i) {
sum_blob.set_data(i, sum_blob.data(i) + (uint8_t)data[i]);
}
} else {
CHECK_EQ(datum.float_data_size(), size_in_datum);
for (int i = 0; i < size_in_datum; ++i) {
sum_blob.set_data(i, sum_blob.data(i) +
static_cast<float>(datum.float_data(i)));
}
}
++count;
if (count % 10000 == 0) {
LOG(INFO) << "Processed " << count << " files.";
}
cursor->Next();
} if (count % 10000 != 0) {
LOG(INFO) << "Processed " << count << " files.";
}
for (int i = 0; i < sum_blob.data_size(); ++i) {
sum_blob.set_data(i, sum_blob.data(i) / count);
}
// Write to disk
if (argc == 3) {
LOG(INFO) << "Write to " << argv[2];
WriteProtoToBinaryFile(sum_blob, argv[2]);
}
const int channels = sum_blob.channels();
const int dim = sum_blob.height() * sum_blob.width();
std::vector<float> mean_values(channels, 0.0);
LOG(INFO) << "Number of channels: " << channels;
for (int c = 0; c < channels; ++c) {
for (int i = 0; i < dim; ++i) {
mean_values[c] += sum_blob.data(dim * c + i);
}
LOG(INFO) << "mean_value channel [" << c << "]:" << mean_values[c] / dim;
}
return 0;
}

【Caffe代码解析】compute_image_mean的更多相关文章

  1. 【Caffe代码解析】Layer网络层

    Layer 功能: 是全部的网络层的基类,当中.定义了一些通用的接口,比方前馈.反馈.reshape,setup等. #ifndef CAFFE_LAYER_H_ #define CAFFE_LAYE ...

  2. 【Caffe代码解析】Blob

    主要功能: Blob 是Caffe作为传输数据的媒介,不管是网络权重參数,还是输入数据,都是转化为Blob数据结构来存储,网络,求解器等都是直接与此结构打交道的. 其直观的能够把它看成一个有4纬的结构 ...

  3. VBA常用代码解析

    031 删除工作表中的空行 如果需要删除工作表中所有的空行,可以使用下面的代码. Sub DelBlankRow() DimrRow As Long DimLRow As Long Dimi As L ...

  4. [nRF51822] 12、基础实验代码解析大全 · 实验19 - PWM

    一.PWM概述: PWM(Pulse Width Modulation):脉冲宽度调制技术,通过对一系列脉冲的宽度进行调制,来等效地获得所需要波形. PWM 的几个基本概念: 1) 占空比:占空比是指 ...

  5. [nRF51822] 11、基础实验代码解析大全 · 实验16 - 内部FLASH读写

     一.实验内容: 通过串口发送单个字符到NRF51822,NRF51822 接收到字符后将其写入到FLASH 的最后一页,之后将其读出并通过串口打印出数据. 二.nRF51822芯片内部flash知识 ...

  6. [nRF51822] 10、基础实验代码解析大全 · 实验15 - RTC

    一.实验内容: 配置NRF51822 的RTC0 的TICK 频率为8Hz,COMPARE0 匹配事件触发周期为3 秒,并使能了TICK 和COMPARE0 中断. TICK 中断中驱动指示灯D1 翻 ...

  7. [nRF51822] 9、基础实验代码解析大全 · 实验12 - ADC

    一.本实验ADC 配置 分辨率:10 位. 输入通道:5,即使用输入通道AIN5 检测电位器的电压. ADC 基准电压:1.2V. 二.NRF51822 ADC 管脚分布 NRF51822 的ADC ...

  8. java集合框架之java HashMap代码解析

     java集合框架之java HashMap代码解析 文章Java集合框架综述后,具体集合类的代码,首先以既熟悉又陌生的HashMap开始. 源自http://www.codeceo.com/arti ...

  9. Kakfa揭秘 Day8 DirectKafkaStream代码解析

    Kakfa揭秘 Day8 DirectKafkaStream代码解析 今天让我们进入SparkStreaming,看一下其中重要的Kafka模块DirectStream的具体实现. 构造Stream ...

随机推荐

  1. 电商平台API接口

  2. Linux 安装 tree命令

    通过yum在线安装tree包 yum install tree -y

  3. linux快速查看同局域网的其他在线主机

    安装一个nmap工具,直接 nmap -sP 192.168.1.1/24 即可

  4. 【LeetCode】Binary Tree Postorder Traversal(二叉树的后序遍历)

    这道题是LeetCode里的第145道题. 题目要求: 给定一个二叉树,返回它的 后序 遍历. 示例: 输入: [1,null,2,3] 1 \ 2 / 3 输出: [3,2,1] 进阶: 递归算法很 ...

  5. JavaScript 专题系列第六篇,讲解深浅拷贝的技巧和以及实现深浅拷贝的思路

    拷贝也是面试经典呐! 数组的浅拷贝 如果是数组,我们可以利用数组的一些方法比如:slice.concat 返回一个新数组的特性来实现拷贝. 比如:   var arr = ['old', 1, tru ...

  6. [转]查看Linux版本信息

    一.查看Linux内核版本命令(两种方法): 1.cat /proc/version [root@S-CentOS home]# cat /proc/version Linux version 2.6 ...

  7. oracle dual表用途及结构详解

    dual是一个虚拟表,用来构成select的语法规则,oracle保证dual里面永远只有一条记录.我们可以用它来做很多事情,如下: 1.查看当前用户,可以在 SQL Plus中执行下面语句 sele ...

  8. wireshark中的抓包过滤器和显示过滤器

    一  抓包过滤器 语法说明:BPF语法(Berkeley Packet Filter) 类型Tpye:host,net,port 方向Dir:src,dst 协议Proto:ether,ip,tcp, ...

  9. hdu 6118 度度熊的交易计划

    度度熊的交易计划 Time Limit: 12000/6000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total S ...

  10. 【CF1015B】Obtaining the String(模拟)

    题意:给定两个字符串,每次可以交换相邻两个字符,给出任意一组交换次数小于1e4的方案使得a串成为b串,输出交换的次数与位置,无解输出-1 n<=50 思路:每次找到第一个不相同的字符,从后面找到 ...