__2017-12-16 如一模式识别研究

如一模式识别研究

vc++>>caffe中调用的第3方库小讨论

boost

Boost库是为C++语言标准库提供扩展的一些C++程序库的总称。boost中国社区地址:http://www.oschina.net/code/tag/boost,这里有一些模版函数。

可下载Boost C++ Libraries安装boost库。大部分boost库功能的使用只需包括相应头文件即可,少数(如正则表达式库,文件系统库等)需要链接库。里面有许多具有工业强度的库,如graph库

Boost库是一个可移植、提供源代码的C++库,作为标准库的后备,是C++标准化进程的开发引擎之一。 Boost库由C++标准委员会库工作组成员发起,其中有些内容有望成为下一代C++标准库内容。在C++社区中影响甚大,是不折不扣的“准”标准库。Boost由于其对跨平台的强调,对标准C++的强调,与编写平台无关。大部分boost库功能的使用只需包括相应头文件即可,少数(如正则表达式库,文件系统库等)需要链接库。但Boost中也有很多是实验性质的东西,在实际的开发中实用需要谨慎。

按照功能分类的Boost库列表

按照实现的功能,Boost可为大致归入以下20个分类,在下面的分类中,有些库同时归入几种类别。

1. 字符串和文本处理

a) Conversion

b) Format

c) IOStream

d) Lexical Cast

e) Regex

f) Spirit

g) String Algo

h) Tokenizer

i) Wave

j) Xpressive

2. 容器

a) Array

b) Bimap

c) Circular Buffer

d) Disjoint Sets

e) Dynamic Bitset

f) GIL

g) Graph

h) ICL

i) Intrusive

j) Multi-Array

k) Multi-Index

l) Pointer Container

m) Property Map

n) Property Tree

o) Unordered

p) Variant

3. 迭代器

a) GIL

b) Graph

c) Iterators

d) Operators

e) Tokenizer

4. 算法

a) Foreach

b) GIL

c) Graph

d) Min-Max

e) Range

f) String Algo

g) Utility

5. 函数对象和高阶编程

a) Bind

b) Function

c) Functional

d) Functional/Factory

e) Functional/Forward

f) Functional/Hash

g) Lambda

h) Member Function

i) Ref

j) Result Of

k) Signals

l) Signals2

m) Utility

6. 泛型编程

a) Call Traits

b) Concept Check

c) Enable If

d) Function Types

e) GIL

f) In Place Factory, Typed In Place Factory

g) Operators

h) Property Map

i) Static Assert

j) Type Traits

7. 模板元编程

a) Function Types

b) Fusion

c) MPL

d) Proto

e) Static Assert

f) Type Traits

8. 预处理元编程

a) Preprocessors

9. 并发编程

a) Asio

b) Interprocess

c) MPI

d) Thread

10. 数学和数字

a) Accumulators

b) Integer

c) Interval

d) Math

e) Math Common Factor

f) Math Octonion

g) Math Quaternion

h) Math/Special Functions

i) Math/Statistical Distributions

j) Multi-Array

k) Numeric Conversion

l) Operators

m) Random

n) Rational

o) uBLAS

11. 排错和测试

a) Concept Check

b) Static Assert

c) Test

12. 数据结构

a) Any

b) Bitmap

c) Compressed Pair

d) Fusion

e) ICL

f) Multi-Index

g) Pointer Container

h) Property Tree

i) Tuple

j) Uuid

k) Variant

13. 图像处理

a) GIL

14. 输入输出

a) Asio

b) Assign

c) Format

d) IO State Savers

e) IOStreams

f) Program Options

g) Serialization

15. 跨语言混合编程

a) Python

16. 内存管理

a) Pool

b) Smart Ptr

c) Utility

17. 解析

a) Spirit

18. 编程接口

a) Function

b) Parameter

19. 杂项

a) Compressed Pair

b) Conversion

c) CRC

d) Date Time

e) Exception

f) Filesystem

g) Flyweight

h) Lexical Cast

i) Meta State Machine

j) Numeric Conversion

k) Optional

l) Polygon

m) Program Options

n) Scope Exit

o) Statechart

p) Swap

q) System

r) Timer

s) Tribool

t) Typeof

u) Units

v) Utility

w) Value Initialized

20. 编译器问题的变通方案

a) Compatibility

b) Config

Boost中比较有名气的有这么几个库:

Regex正则表达式库

Spirit ,LL parser framework,用C++代码直接表达EBNF

Graph图组件和算法

Lambda在调用的地方定义短小匿名的函数对象,很实用的functional功能

concept check检查泛型编程中的concept

Mpl用模板实现的元编程框架

Thread可移植的C++多线程库

Python把C++类和函数映射到Python之中

Pool内存池管理

smart_ptr,5个智能指针,学习智能指针必读,一份不错的参考是来自CUJ的文章:

gflags

gflags是google的一个开源的处理命令行参数的库,使用c++开发,具备python接口,可以替代getopt。
gflags使用起来比getopt方便,但是不支持参数的简写(例如getopt支持--list缩写成-l,gflags不支持)。
如何安装使用gflags:
安装:请访问地址https://code.google.com/p/gflags/,下载最新版的gflags,编译安装。
使用:
  1. 首先需要include "gflags.h"(废话,-_-b)
    #include 
    
  2. 将需要的命令行参数使用gflags的宏:DEFINE_xxxxx(变量名,默认值,help-string) 定义在文件当中,注意全局域哦。gflags支持以下类型:
    • DEFINE_bool: boolean
    • DEFINE_int32: 32-bit integer
    • DEFINE_int64: 64-bit integer
    • DEFINE_uint64: unsigned 64-bit integer
    • DEFINE_double: double
    • DEFINE_string: C++ string
  3. 在main函数中加入:(一般是放在main函数的头几行,越早了解用户的需求越好么^_^)
    google::ParseCommandLineFlags(&argc, &argv, true);
    
    argc和argv想必大家都很清楚了,说明以下第三个参数的作用:
    
    如果设为true,则该函数处理完成后,argv中只保留argv[0],argc会被设置为1。
    
    如果为false,则argv和argc会被保留,但是注意函数会调整argv中的顺序。
    
  4. 这样,在后续代码中可以使用FLAGS_变量名访问对应的命令行参数了
    printf("%s", FLAGS_mystr);
    
  5. 最后,编译成可执行文件之后,用户可以使用:executable --参数1=值1 --参数2=值2 ... 来为这些命令行参数赋值。
    ./mycmd --var1="test" --var2=3.141592654 --var3=32767 --mybool1=true --mybool2 --nomybool3
    
    这里值得注意的是bool类型命令行参数,除了可以使用--xxx=true/false之外,还可以使用--xxx和--noxxx后面不加等号的方式指定true和false

gflags的使用

使用flags需要包含头文件  #include   gflags主要支持的参数类型包括bool,int32, int64, uint64, double, string等,定义参数通过DEFINE_type宏实现,如下所示,分别定义了一个bool和一个string类型的参数,该宏的三个参数含义分别为命令行参数名,参数默认值,以及参数的帮助信息。 

DEFINE_bool(big_menu, true, "Include 'advanced' options in the menu listing"); 
DEFINE_string(languages, "english,french,german", 
                 "comma-separated list of languages to offer in the 'lang' menu");
gflag不支持列表,用户通过灵活借助string参数实现,比如上述的languages参数,可以类型为string,但可看作是以逗号分割的参数列表。 

定义以上参数后,就需要在main()函数中执行gflags::ParseCommandLineFlags(&argc, &argv, true);

然后就可以在应用程序中使用FLAGS_big_menu、FLAGS_languages表示获取到的命令行参数值。

glog

手册地址:http://google-glog.googlecode.com/svn/trunk/doc/glog.html

 简单中文参考:http://blog.csdn.net/netlinux/article/details/6700549,http://www.cnblogs.com/sbaicl/archive/2012/08/30/2663487.html
Google glog是一个基于程序级记录日志信息的c++库,编程使用方式与c++的stream操作类似,例:
LOG(INFO) << "Found " << num_cookies << " cookies";
“LOG”宏为日志输出关键字,“INFO”为严重性程度。
主要支持功能:
1, 参数设置,以命令行参数的方式设置标志参数来控制日志记录行为;
2, 严重性分级,根据日志严重性分级记录日志;
3, 可有条件地记录日志信息;
4, 条件中止程序。丰富的条件判定宏,可预设程序终止条件;
5, 异常信号处理。程序异常情况,可自定义异常处理过程;
6, 支持debug功能。可只用于debug模式;
7, 自定义日志信息;
8, 线程安全日志记录方式;
9, 系统级日志记录;
10, google perror风格日志信息;
11, 精简日志字符串信息。

完成配置后的例程如下:

#include

#include

using namespace std;

 int main(int argc, char* argv[]) {     

  // Initialize Google's logging library.     

  google::InitGoogleLogging(argv[0]);  

  google::LogToStderr();//只输出到标准错误输出

         LOG(INFO) <<"my first info";   int valueint=10;  

   LOG_IF(ERROR, valueint=10)<<" valueint=10";

    system("pause");

  }

结果如下:

I0830 12:06:04.306638  5684 body.cpp:12] my first info

E0830 12:06:04.311637  5684 body.cpp:14]  valueint=10

请按任意键继续. . .

google/protobuf

后续详细查看:http://www.ibm.com/developerworks/cn/linux/l-cn-gpb/

后续详细查看:http://blog.csdn.net/caisini_vc/article/details/5599468

除了性能好,代码生成机制是主要吸引俺的地方。为了说明这个代码生成机制,俺举个例子。

  比如有个电子商务的系统(假设用C++实现),其中的模块A需要发送大量的订单信息给模块B,通讯的方式使用socket。

假设订单包括如下属性:

--------------------------------

  时间:time(用整数表示)

  客户id:userid(用整数表示)

  交易金额:price(用浮点数表示)

  交易的描述:desc(用字符串表示)

--------------------------------

  如果使用protobuf实现,首先要写一个proto文件(不妨叫Order.proto),在该文件中添加一个名为"Order"的message结构,用来描述通讯协议中的结构化数据。该文件的内容大致如下:

 

--------------------------------

message Order

{

  required int32 time = 1;

  required int32 userid = 2;

  required float price = 3;

  optional string desc = 4;

}

--------------------------------

 

  然后,使用protobuf内置的编译器编译 该proto。由于本例子的模块是C++,你可以通过protobuf编译器的命令行参数(看“这里 ”),让它生成C++语言的“订单包装类”。(一般来说,一个message结构会生

成一个包装类)

  然后你使用类似下面的代码来序列化/解析该订单包装类:

--------------------------------

// 发送方

Order order;

order.set_time(XXXX);

order.set_userid(123);

order.set_price(100.0f);

order.set_desc("a test order");

string sOrder;

order.SerailzeToString(&sOrder);

// 然后调用某种socket的通讯库把序列化之后的字符串发送出去

// ......

--------------------------------

// 接收方

string sOrder;

// 先通过网络通讯库接收到数据,存放到某字符串sOrder

// ......

Order order;

if(order.ParseFromString(sOrder))  // 解析该字符串

{

  cout << "userid:" << order.userid() << endl

          << "desc:" << order.desc() << endl;

}

else

{

  cerr << "parse error!" << endl;

}

--------------------------------

 

  有了这种代码生成机制,开发人员再也不用吭哧吭哧地编写那些协议解析的代码了(干这种活是典型的吃力不讨好)。

  万一将来需求发生变更,要求给订单再增加一个“状态”的属性,那只需要在Order.proto文件中增加一行代码。对于发送方(模块A),只要增加一行设置状态的代码;对于接收方(模块B)只要增加一行读取状

态的代码。哇塞,简直太轻松了!

  另外,如果通讯双方使用不同的编程语言来实现,使用这种机制可以有效确保两边的模块对于协议的处理是一致的。

  顺便跑题一下。

  从某种意义上讲,可以把proto文件看成是描述通讯协议的规格说明书(或者叫接口规范)。这种伎俩其实老早就有了,搞过微软的COM编程或者接触过CORBA的同学,应该都能从中看到IDL(详细解释看“这里 ”

)的影子。它们的思想是相通滴。

Protocol Buffers 是一种轻便高效的结构化数据存储格式,可以用于结构化数据串行化,很适合做数据存储或 RPC 数据交换格式。它可用于通讯协议、数据存储等领域的语言无关、平台无关、可扩展的序列化结构数据格式。目前提供了 C++、Java、Python 三种语言的 API。

Protobuf 的优点

Protobuf 有如 XML,不过它更小、更快、也更简单。你可以定义自己的数据结构,然后使用代码生成器生成的代码来读写这个数据结构。你甚至可以在无需重新部署程序的情况下更新数据结构。只需使用 Protobuf 对数据结构进行一次描述,即可利用各种不同语言或从各种不同数据流中对你的结构化数据轻松读写。

它有一个非常棒的特性,即“向后”兼容性好,人们不必破坏已部署的、依靠“老”数据格式的程序就可以对数据结构进行升级。这样您的程序就可以不必担心因为消息结构的改变而造成的大规模的代码重构或者迁移的问题。因为添加新的消息中的 field 并不会引起已经发布的程序的任何改变。

Protobuf 语义更清晰,无需类似 XML 解析器的东西(因为 Protobuf 编译器会将 .proto 文件编译生成对应的数据访问类以对 Protobuf 数据进行序列化、反序列化操作)。

使用 Protobuf 无需学习复杂的文档对象模型,Protobuf 的编程模式比较友好,简单易学,同时它拥有良好的文档和示例,对于喜欢简单事物的人们而言,Protobuf 比其他的技术更加有吸引力。

Protobuf 的不足

Protbuf 与 XML 相比也有不足之处。它功能简单,无法用来表示复杂的概念。

XML 已经成为多种行业标准的编写工具,Protobuf 只是 Google 公司内部使用的工具,在通用性上还差很多。

由于文本并不适合用来描述数据结构,所以 Protobuf 也不适合用来对基于文本的标记文档(如 HTML)建模。另外,由于 XML 具有某种程度上的自解释性,它可以被人直接读取编辑,在这一点上 Protobuf 不行,它以二进制的方式存储,除非你有 .proto 定义,否则你没法直接读出 Protobuf 的任何内容【 2 】。

hdf5

关于HDF文件的一点概述(HDF4,HDF5) | 麻辣GIS

HDF5数据格式是科学计算一体化数据格式,常用于卫星遥感影像的外部存储。

HDF5是一个层次型的数据存储格式,包含了数据定义和支持接口。HDF5比较适合用于那些复杂的科学数据,无法用一般的格式存放。HDF5还支持用户自定义层次型组成的各种各样的数据结构和属性。而且HDF5也可以运行在并行MPI IO上,可以到其官方站点http://hdf.nasa.uiuc.edu/hdf5一睹其究竟。

Hierarchical Data Format,可以存储不同类型的图像和数码数据的文件格式,并且可以在不同类型的机器上传输,同时还有统一处理这种文件格式的函数库。大多数普通计算机都支持这种文件格式

http://baike.baidu.com/link?url=nsDJAKi9gXFuggbxEC-Uh3hKfEDi-ieXaRjMXTG-mJ7p1s-bE8tI16jTgaH9eulqIz1GVKa-x-d7jFN0Znwa8a

文件格式是指计算机存储和处理数据的方式 。目前常用的图像文件格式很多, 如 GIF , JPG , PCX ,TIFF 等 。这些格式共同的缺点是结构太简单 ,不能存放除影像信息外其他的有用数据 ,像遥感影像的坐标值、参数等都无法在其中保存 ,而且用不同格式存储影像数据使得读取 、传输、共享变得复杂, 因此,有必要建立一种标准格式以解决上述问题。
HDF(Hierarchical Data File)是美国国家高级计算应用中心(National Center for Supercomputing Application,NCSA)为了满足各种领域研究需求而研制的一种能高效存储和分发科学数据的新型数据格式 。HDF可以表示出科学数据存储和分布的许多必要条件。HDF被设计为:
自述性:对于一个HDF文件里的每一个数据对象,有关于该数据的综合信息(元数据)。在没有任何外部信息的情况下,HDF允许应用程序解释HDF文件的结构和内容。
通用性:许多数据类型都可以被嵌入在一个HDF文件里。例如,通过使用合适的HDF数据结构,符号、数字和图形数据可以同时存储在一个HDF文件里。
灵活性:HDF允许用户把相关的数据对象组合在一起,放到一个分层结构中,向数据对象添加描述和标签。它还允许用户把科学数据放到多个HDF文件里。
扩展性:HDF极易容纳将来新增加的数据模式,容易与其他标准格式兼容。
跨平台性:HDF是一个与平台无关的文件格式。HDF文件无需任何转换就可以在不同平台上使用。
科学家通常在不同的机器上生成和处理数据文件。各式各样的软件包被用来多种处理文件,同时也与其他使用不同机器和软件的人共享数据文件。在一组文件里,这些文件也许包含不同类型的信息。这些不同类型的信息混合结构在一个文件里的意义与在另一个文件里的意义不同。这些文件也许概念上有关但在实质上却不同。例如,一些数据(符号、数字和图形)也许在不同文件中被分开,但在程序中却是在一起。有些数据也许在科学家的概念中是相关的,但实际上并不存在物理联系。HDF通过提供一个一般目的的文件结构来表明这些问题:HDF为程序提供一个从数据文件本身获取数据(数据元)信息的机制,而不是其他来源[1]  。
使用户把不同来源的混合数据存放在一个文件里,同时也可以把数据和与之相关的信息存放在不同的文件里,即便是用同一个应用程序也可以处理这些文件。常用的许多类型数据集,如光栅图像多维数组,对其格式和描述实行标准化。支持使用标准的数据格式,因为所有的机器和程序都会生成一个有明确含义的数据文件。HDF实质上能被用于任何类型的数据[1]  。
HDF 最初产生于 20 世纪 80 年代 , 到现在已经具有两个不同的产品。从 HDF1 到 HDF4 的各个版本在本质上是一致的 , 因而 HDF4 可以向后兼容早期的版本 。HDF5 推出于 1998 年, 相较于以前的HDF 文件, 可以说是一种全新的文件格式, 它与HDF4 只在概念上一脉相承 ,而在数据结构的组织上却截然迥异。HDF5 的产生与发展反映了 HDF 在不断适应现代计算机发展和数据处理日益庞大复杂的要求。HDF5 紧跟时代变化也为其自身注入活力,使它被愈来愈多的领域采纳、运用 ,许多遥感影像采取HDF 格式存取, 一些大的图像处理软件也开始提供接口读取 HDF 文件。 HDF 强大的机制适应了遥感影像的特点 ,能够有条不紊 、完备地保存遥感影像的属性和空间信息数据 , 同时使查询和提取相关数据也很方便容易 。
详细请看下面链接:

HDF_百度百科 

leveldb

RocksDB介绍:一个比LevelDB更彪悍的引擎 | UC技术博客

Leveldb是一个google实现的非常高效的kv数据库,目前的版本1.2能够支持billion级别的数据量了

LevelDb之二:整体架构-zpf1218-ChinaUnix博客

数据分析与处理之二(Leveldb 实现原理) - Haippy - 博客园

level db一个key-value型的数据库
LevelDB本身只是一个lib库,在源码目录make编译即可,然后在我们的应用程序里面可以直接include leveldb/include/db.h头文件,该头文件有几个基本的数据库操作接口,下面是一个测试例子:

#include 
#include 
#include     
#include "leveldb/db.h"    

using namespace std;

int main(void) 
{       

    leveldb::DB      *db;    
    leveldb::Options  options;    
    options.create_if_missing = true;    

    // open
    leveldb::Status status = leveldb::DB::Open(options,"/tmp/testdb", &db);    
    assert(status.ok());    

    string key = "name";    
    string value = "chenqi";    

    // write
    status = db->Put(leveldb::WriteOptions(), key, value);    
    assert(status.ok());    

    // read
    status = db->Get(leveldb::ReadOptions(), key, &value);    
    assert(status.ok());    

    cout<<value<Delete(leveldb::WriteOptions(), key);    
    assert(status.ok());        

    status = db->Get(leveldb::ReadOptions(),key, &value);    
    if(!status.ok()) {
        cerr<<key<<"    "<<status.ToString()<<endl;
    } else {
        cout<<key<<"==="<<value<<endl;    
    }   

    // close 
    delete db;    

    return 0;    
}
上面的例子演示了如何插入、获取、删除一条记录,编译代码:

g++ -o test test.cpp libleveldb.a -lpthread -Iinclude
执行./test后,会在/tmp下面生成一个目录testdb,里面包含若干文件:

http://images.cnitblog.com/blog/603001/201410/141839461693674.jpg

openBLAS

比较OpenBLAS,Intel MKL和Eigen的矩阵相乘性能 | LiXiang

OpenBLAS - Browse Files at SourceForge.net

OpenBLAS : An optimized BLAS library

OpenBLAS首页、文档和下载 - 高性能多核 BLAS 库 - 开源中国社区

...日】演讲嘉宾-张先轶老师演讲速记:开源的高性能BLAS实现OpenBLAS

从这个几个链接中,可以看到 openblas是高性能多核心的一个库

OpenBLAS是高性能多核BLAS库,是GotoBLAS2 1.13 BSD版本的衍生版。项目主页是 https://github.com/xianyi/OpenBLAS 。

通常的编译安装流程如下:

  • make CC=gcc-4.7 FC=gfortran (通常情况下,make会进行自动探测,够用了)
  • make PREFIX=/your/path install  (可选) 

其中,make过程会自动的探测当前机器和编译环境,设置合适的选项。需注意的是,OpenBLAS会下载netlib上的LAPACK源代码。也就是说你的机器必须联网,或者放入lapack的源代码包,或者不包括LAPACK即make NO_LAPACK=1。

如果自动探测不够用,可以考虑下面几个常用选项,具体请参考Makefile.rule文件:

  • 编译32位或者64位, make BINARY=32 或者 make BINARY=64 (如果不设置,会自动探测)
  • 设置目标CPU,比如目标CPU为sandybridge或者nehalem,make TARGET=SANDYBRIDGE 或者 make TARGET=NEHALEM (如果不设置,会自动探测)
  • 在x86/x86_64架构上,程序库包含多个CPU的汇编优化代码,make DYNAMIC_ARCH=1
  • 不包含CBLAS接口,make NO_CBLAS=1
  • 不包含LAPACK, make NO_LAPACK=1
  • 包含LAPACK,但是不包含LAPACKE接口,make NO_LAPACKE=1
  • 编译单线程库, make USE_THREAD=0 (如果不设置为0,会自动探测是否多核处理器,默认使用pthread并行)
  • 编译OpenMP多线程库,make USE_OPENMP=1
  • 设置最大线程数量为n,make NUM_THREADS=n
  • 禁用CPU亲和性,make NO_AFFINITY=1

opencv

评论留言区

:
  

作者: 游客 ; *
评论内容: *
带*号为必填项目

如一模式识别更新提示

matlab在图像处理方面的应用有更新

如一模式识别 友情链接

关于本站作者     chinaw3c     mozilla