文档库 最新最全的文档下载
当前位置:文档库 › snort源码分析

snort源码分析

snort源码分析
snort源码分析

源码分析

Snort作为一个轻量级的网络入侵检测系统,在实际中应用可能会有些力不从心,但如果想了

解研究IDS的工作原理,仔细研究一下它的源码到是非常不错.首先对snort做一个概括的评论。

从工作原理而言,snort是一个NIDS。[注:基于网络的入侵检测系统(NIDS)在网络的一点被动地检查原始的网络传输数据。通过分析检查的数据包,NIDS匹配入侵行为的特征或者从网络活动的角度检测异常行为。] 网络传输数据的采集利用了工具包libpcap。snort对libpcap采集来的数据进行分析,从而判断是否存在可疑的网络活动。

从检测模式而言,snort基本上是误用检测(misuse detection)。[注:该方法对已知攻击的特征模式进行匹配,包括利用工作在网卡混杂模式下的嗅探器被动地进行协议分析,以及对一系列数据包解释分析特征。顺便说一句,另一种检测是异常检测(anomaly detection)。]具体实现上,仅仅是对数据进行最直接最简单的搜索匹配,并没有涉及更复杂的入侵检测办法。

尽管snort在实现上没有什么高深的检测策略,但是它给我们提供了一个非常

优秀的公开源代码的入侵检测系统范例。我们可以通过对其代码的分析,搞清IDS 究竟是如何工作的,并在此基础上添加自己的想法。

snort的编程风格非常优秀,代码阅读起来并不困难,整个程序结构清晰,函

数调用关系也不算复杂。但是,snort的源文件不少,函数总数也很多,所以不太

容易讲清楚。因此,最好把代码完整看一两遍,能更清楚点。

*****************************************************

*****************************************************

下面看看snort的整体结构。展开snort压缩包,有约50个c程序和头文件,另有约30个其它文件(工程、数据或者说明文件)。[注:这里用的是snort-1.6-beta7。snort-1.6.3不在手边,就用老一点的版本了,差别不大。]下面对源代码文件分组说明。

snort.c(.h)是主程序所在的文件,实现了main函数和一系列辅助函数。

decode.c(.h)把数据包层层剥开,确定该包属于何种协议,有什么特征。并

标记到全局结构变量pv中。

log.c(.h)实现日志和报警功能。snort有多种日志格式,一种是按tcpdump二进制的格式存储,另一种按snort编码的ascii格式存储在日志目录下,日志目录的名字根据"外"主机的ip 地址命名。报警有不同的级别和方式,可以记录到syslog中,或者记录到用户指定的文件,另外还可以通过unix socket发送报警消息,以及利用SMB向Windows系统发送winpopup 消息。

mstring.c(.h)实现字符串匹配算法。在snort中,采用的是Boyer-Moore算法。算法书上一般都有。

plugbase.c(.h)实现了初始化检测以及登记检测规则的一组函数。snort中的检测规则以链表的形式存储,每条规则通过登记(Register)过程添加到链表中。

response.c(.h)进行响应,即向攻击方主动发送数据包。这里实现了两种响应。一种是发送ICMP的主机不可到达的假信息,另一种针对TCP,发送RST包,断开连接。

rule.c(.h)实现了规则设置和入侵检测所需要的函数。规则设置主要的作用是

把一个规则文件转化为实际运作中的规则链表。检测函数根据规则实施攻击特征的检测。

sp_*_check.c(.h)是不同类型的检测规则的具体实现。很容易就可以从文件名得知所实现的规则。例如,sp_dsize_check针对的是包的数据大小,sp_icmp_type_check针对icmp包的类型,sp_tcp_flag_check针对tcp包的标志位。不再详述。

spo_*.c(.h)实现输出(output)规则。spo_alert_syslog把事件记录到syslog中;spo_log_tcpdump 利用libpcap中的日志函数,进行日志记录。

spp_*.c(.h)实现预处理(preprocess)规则。包括http解码(即把http请求中的%XX这样的字符用对应的ascii字符代替,避免忽略了恶意的请求)、最小片断检查(避免恶意利用tcp 协议中重组的功能)和端口扫描检测。

******************************************************************************* *************************** 下面描述main函数的工作流程。先来说明两个结构的定义。

在snort.h中,定义了两个结构:PV和PacketCount。PV用来记录命令行参数,snort根据这些命令行参数来确定其工作方式。PV类型的全局变量pv用来实际记录具体工作方式。结构定义可以参看snort.h,在下边的main函数中,会多次遇到pv中各个域的设定,到时再一个一个解释。

结构PacketCount用来统计流量,每处理一个数据包,该结构类型的全局变量pc把对应的域加1。相当于一个计数器。

接下来解释main函数。

初始化设定一些缺省值;然后解析命令行参数,根据命令行参数,填充结构变量pv;根据pv的值(也就是解析命令行的结果)确定工作方式,需要注意:

如果是运行在Daemon方式,通过GoDaemon函数,创建守护进程,重定向标准输入输出,实现daamon状态,并结束父进程。

snort可以实时采集网络数据,也可以从文件读取数据进行分析。这两种情况并没有本质区别。如果是读取文件进行分析(并非直接从网卡实时采集来的),以该文件名作为libpcap

的函数OpenPcap的参数,打开采集过程;如果是从网卡实时采集,就把网卡接口作为OpenPcap的参数,利用libpcap的函数打开该网卡接口。在unix中,设备也被看作是文件,所以这和读取文件分析没有多大的差别。

接着,指定数据包的拆包函数。不同的数据链路网络,拆包的函数也不同。利用函数

SetPktProcessor,根据全局变量datalink的值,来设定不同的拆包函数。例如,以太网,拆包函数为DecodeEthPkt;令牌环网,拆包函数为DecodeTRPkt,等等。这些Decode*函数,在decode.c中实现。

如果使用了检测规则,那么下面就要初始化这些检测规则,并解析规则文件,转化成规则链表。规则有三大类:预处理(preprocessor),插件(plugin),输出插件(outputplugin)。这里plugin就是具体的检测规则,而outputplugin是定义日志和报警方式的规则。

然后根据报警模式,设定报警函数;根据日志模式,设定日志函数;如果指定了能够进行响应,就打开raw socket,准备用于响应。

最后进入读取数据包的循环,pcap_loop对每个采集来的数据包都用ProcessPacket函数进行处理,如果出现错误或者到达指定的处理包数(pv.pkt_cnt定义),就退出该函数。这里ProcessPacket是关键程序,

最后,关闭采集过程。

*****************************************************

现在看看snort如何实现对数据包的分析和检测入侵的。

在main函数的最后部分有如下语句,比较重要:

/* Read all packets on the device. Continue until cnt packets read */

if(pcap_loop(pd, pv.pkt_cnt, (pcap_handler)ProcessPacket, NULL) < 0)

{

......

}

这里pcap_loop函数有4个参数,分别解释:

pd是一个全局变量,表示文件描述符,在前面OpenPcap的调用中已经被正确地赋值。前面说过,snort可以实时采集网络数据,也可以从文件读取数据进行分析。在不同情况打开文件(或设备)时,pd分别用来处理文件,或者网卡设备接口。

pd是struct pcap类型的指针,该结构包括实际的文件描述符,缓冲区,等等域,用来处理从相应的文件获取信息。

OpenPcap函数中对pd赋值的语句分别为:

/* get the device file descriptor,打开网卡接口*/

pd = pcap_open_live(pv.interface, snaplen,

pv.promisc_flag ? PROMISC : 0, READ_TIMEOUT, errorbuf);

或者

/* open the file,打开文件*/

pd = pcap_open_offline(intf, errorbuf);

于是,这个参数表明从哪里取得待分析的数据。

第2个参数是pv.pkt_cnt,表示总共要捕捉的包的数量。在main函数初始化时,缺省设置为-1,成为永真循环,一直捕捉直到程序退出:

/* initialize the packet counter to loop forever */

pv.pkt_cnt = -1;

或者在命令行中设置要捕捉的包的数量。前面ParseCmdLine(解析命令行)函数的调用中,遇到参数n,重新设定pv.pkt_cnt的值。ParseCmdLine中相关语句如下:

case 'n': /* grab x packets and exit */

pv.pkt_cnt = atoi(optarg);

第3个参数是回调函数,该回调函数处理捕捉到的数据包。这里为函数ProcessPacket,下面将详细解释该函数。

第4个参数是字符串指针,表示用户,这里设置为空。

在说明处理包的函数ProcessPacket之前,有必要解释一下pcap_loop的实现。我们看到main 函数只在if条件判断中调用了一次pacp_loop,那么循环一定是在pcap_loop中做的了。察看pcap.c文件中pcap_loop的实现部分,我们发现的确如此:

int

pcap_loop(pcap_t *p, int cnt, pcap_handler callback, u_char *user)

{

register int n;

for (; { //for循环

if (p->sf.rfile != NULL)

n = pcap_offline_read(p, cnt, callback, user);

else {

/*

* XXX keep reading until we get something

* (or an error occurs)

*/

do { //do循环

n = pcap_read(p, cnt, callback, user);

} while (n == 0);

}

if (n <= 0)

return (n); //遇到错误,返回

if (cnt > 0) {

cnt -= n;

if (cnt <= 0)

return (0); //到达指定数量,返回

}

//只有以上两种返回情况

}

}

现在看看ProcessPacket的实现了,这个回调函数用来处理数据包。该函数是是pcap_handler 类型的,pcap.h中类型的定义如下:

typedef void (*pcap_handler)(u_char *, const struct pcap_pkthdr *,

const u_char *);

第1个参数这里没有什么用;

第2个参数为pcap_pkthdr结构指针,记录时间戳、包长、捕捉的长度;

第3个参数字符串指针为数据包。

函数如下:

void ProcessPacket(char *user, struct pcap_pkthdr *pkthdr, u_char *pkt)

{

Packet p; //Packet结构在decode.h中定义,用来记录数据包的各种信息

/* call the packet decoder,调用拆包函数,这里grinder是一个全局

函数指针,已经在main的SetPktProcessor调用中设置为正确的拆包函数*/

(*grinder)(&p, pkthdr, pkt);

/* print the packet to the screen,如果选择了详细显示方式,

那么把包的数据,显示到标准输出*/

if(pv.verbose_flag)

{

...... //省略

}

/* check or log the packet as necessary

如果工作在使用检测规则的方式,就调用Preprocess进行检测,

否则,仅仅进行日志,记录该包的信息*/

if(!https://www.wendangku.net/doc/6015360451.html,e_rules)

{

... //进行日志,省略

}

else

{

Preprocess(&p);

}

//清除缓冲区

ClearDumpBuf();

}

这里Preprocess函数进行实际检测。

**************************************************************************** Proprocess函数很短,首先调用预处理规则处理数据包p,然后调用检测

函数Detect进行规则匹配实现检测,如果实现匹配,那么调用函数CallOutput

Plugins根据输出规则进行报警或日志。函数如下:

void Preprocess(Packet *p)

{

PreprocessFuncNode *idx;

do_detect = 1;

idx = PreprocessList; //指向预处理规则链表头

while(idx != NULL) //调用预处理函数处理包p

{

idx->func(p);

idx = idx->next;

}

if(!p->frag_flag && do_detect)

{

if(Detect(p)) //调用检测函数

{

CallOutputPlugins(p); //如果匹配,根据规则输出

}

}

}

尽管这个函数很简洁,但是在第1行我们看到定义了ProprocessFuncNode

结构类型的指针,所以下面,我们不得不开始涉及到snort的各种复杂

的数据结构。前面的分析,我一直按照程序运行的调用顺序,忽略了许多函

数(其实有不少非常重要),以期描述出snort执行的主线,避免因为程序中

大量的调用关系而产生混乱。到现在,我们还没有接触到snort核心的数据结构

和算法。有不少关键的问题需要解决:规则是如何静态描述的?运行时这些

规则按照什么结构动态存储?每条规则的处理函数如何被调用?snort给了

我们提供了非常好的方法。

snort一个非常成功的思想是利用了plugin机制,规则处理函数并非固定在

源程序中,而是根据每次运行时的参数设定,从规则文件中读入规则,再把每个规则所需要的处理函数挂接到链表上。实际检测时,遍历这些链表,调用链表上相应的函数来分析。

snort主要的数据结构是链表,几乎都是链表来链表去。我们下面做个总的

介绍。

我们有必要先回过头来,看一看main函数中对规则初始化时涉及到的一些

数据结构。

在main函数初始化规则的时候,先建立了几个链表,全局变量定义如下(plugbase.c中):

KeywordXlateList *KeywordList;

PreprocessKeywordList *PreprocessKeywords;

PreprocessFuncNode *PreprocessList;

OutputKeywordList *OutputKeywords;

OutputFuncNode *OutputList;

这几种结构的具体定义省略。这一初始化的过程把snort中预定义的关键

字和处理函数按类别连接在不同的链表上。然后,在解析规则文件的时候,

如果一条规则的选项中包含了某个关键字,就会从上边初始化好的对应的链表中查找,把必要的信息和处理函数添加到表示这条规则的节点(用RuleTreeNode 类型来表示,下面详述)的特定域(OptTreeNode类型)中。

同时,main函数中初始化规则的最后,对指定的规则文件进行解析。在最

高的层次上,有3个全局变量保存规则(rules.c):

ListHead Alert; /* Alert Block Header */

ListHead Log; /* Log Block Header */

ListHead Pass; /* Pass Block Header */

这几个变量是ListHead类型的,正如名称所说,指示链表头。Alert中登记

了需要报警的规则,Log中登记了需要进行日志的规则,Pass中登记的规则在处理过程忽略(不进行任何处理)。ListHead定义如下:

typedef struct _ListHead

{

RuleTreeNode *TcpList;

RuleTreeNode *UdpList;

RuleTreeNode *IcmpList;

} ListHead;

可以看到,每个ListHead结构中有三个指针,分别指向处理Tcp/Udp/Icmp包规则的链表头。这里又出现了新的结构RuleTreeNode,为了说明链表的层次关系,下面列出RuleTreeNode 的定义,但是忽略了大部分域:

typedef struct _RuleTreeNode

{

RuleFpList *rule_func;

...... //忽略

struct _RuleTreeNode *right;

OptTreeNode *down; /* list of rule options to associate with this

rule node */

} RuleTreeNode;

RuleTreeNode中包含上述3个指针域,分别又能形成3个链表。RuleTreeNode*类型的right 指向下一个RuleTreeNode,相当于普通链表中的next域,只不过这里用right来命名。这样就形成了规则链表。

RuleFpList类的指针rule_func记录的是该规则的处理函数的链表。一条规则有时候需要调用多个处理函数来分析。所以,有必要做成链表。我们看看下面的定义,除了next域,还有一个函数指针:

typedef struct _RuleFpList

{

/* rule check function pointer */

int (*RuleHeadFunc)(Packet *, struct _RuleTreeNode *, struct _RuleFpList *);

/* pointer to the next rule function node */

struct _RuleFpList *next;

} RuleFpList;

第3个指针域是OptTreeNode类的指针down,该行后面的注释说的很清楚,这是与这个规则节点相联系的规则选项的链表。很不幸,OptTreeNode的结构也相当复杂,而且又引出了几个新的链表。忽略一些域,OptTreeNode定义如下:

typedef struct _OptTreeNode

{

/* plugin/detection functions go here */

OptFpList *opt_func;

/* the ds_list is absolutely essential for the plugin system to work,

it allows the plugin authors to associate "dynamic" data structures

with the rule system, letting them link anything they can come up

with to the rules list */

void *ds_list[512]; /* list of plugin data struct pointers */

.......//省略了一些域

struct _OptTreeNode *next;

} OptTreeNode;

next指向链表的下一个节点,无需多说。OptFpList类型的指针opt_func指向

选项函数链表,同前面说的RuleFpList没什么大差别。值得注意的是指针数组

ds_list,用来记录该条规则中涉及到的预定义处理过程。每个元素的类型是void*.在实际表示规则的时候,ds_list被强制转换成不同的预定义类型。

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

Proprocess函数很短,首先调用预处理规则处理数据包p,然后调用检测

函数Detect进行规则匹配实现检测,如果实现匹配,那么调用函数CallOutput

Plugins根据输出规则进行报警或日志。函数如下:

void Preprocess(Packet *p)

{

PreprocessFuncNode *idx;

do_detect = 1;

idx = PreprocessList; //指向预处理规则链表头

while(idx != NULL) //调用预处理函数处理包p

{

idx->func(p);

idx = idx->next;

}

if(!p->frag_flag && do_detect)

{

if(Detect(p)) //调用检测函数

{

CallOutputPlugins(p); //如果匹配,根据规则输出

}

}

尽管这个函数很简洁,但是在第1行我们看到定义了ProprocessFuncNode

结构类型的指针,所以下面,我们不得不开始涉及到snort的各种复杂

的数据结构。前面的分析,我一直按照程序运行的调用顺序,忽略了许多函

数(其实有不少非常重要),以期描述出snort执行的主线,避免因为程序中

大量的调用关系而产生混乱。到现在,我们还没有接触到snort核心的数据结构和算法。有不少关键的问题需要解决:规则是如何静态描述的?运行时这些

规则按照什么结构动态存储?每条规则的处理函数如何被调用?snort给了

我们提供了非常好的方法。

snort一个非常成功的思想是利用了plugin机制,规则处理函数并非固定在

源程序中,而是根据每次运行时的参数设定,从规则文件中读入规则,再把每个规则所需要的处理函数挂接到链表上。实际检测时,遍历这些链表,调用链表上相应的函数来分析。

snort主要的数据结构是链表,几乎都是链表来链表去。我们下面做个总的

介绍。

我们有必要先回过头来,看一看main函数中对规则初始化时涉及到的一些

数据结构。

在main函数初始化规则的时候,先建立了几个链表,全局变量定义如下(plugbase.c中):

KeywordXlateList *KeywordList;

PreprocessKeywordList *PreprocessKeywords;

PreprocessFuncNode *PreprocessList;

OutputKeywordList *OutputKeywords;

OutputFuncNode *OutputList;

这几种结构的具体定义省略。这一初始化的过程把snort中预定义的关键

字和处理函数按类别连接在不同的链表上。然后,在解析规则文件的时候,

如果一条规则的选项中包含了某个关键字,就会从上边初始化好的对应的链表中查找,把必要的信息和处理函数添加到表示这条规则的节点(用RuleTreeNode 类型来表示,下面详述)的特定域(OptTreeNode类型)中。

同时,main函数中初始化规则的最后,对指定的规则文件进行解析。在最

高的层次上,有3个全局变量保存规则(rules.c):

ListHead Alert; /* Alert Block Header */

ListHead Log; /* Log Block Header */

ListHead Pass; /* Pass Block Header */

这几个变量是ListHead类型的,正如名称所说,指示链表头。Alert中登记

了需要报警的规则,Log中登记了需要进行日志的规则,Pass中登记的规则在处

理过程忽略(不进行任何处理)。ListHead定义如下:

typedef struct _ListHead

{

RuleTreeNode *TcpList;

RuleTreeNode *UdpList;

RuleTreeNode *IcmpList;

} ListHead;

可以看到,每个ListHead结构中有三个指针,分别指向处理Tcp/Udp/Icmp包规则的链表头。这里又出现了新的结构RuleTreeNode,为了说明链表的层次关系,下面列出RuleTreeNode的定义,但是忽略了大部分域:

typedef struct _RuleTreeNode

{

RuleFpList *rule_func;

...... //忽略

struct _RuleTreeNode *right;

OptTreeNode *down; /* list of rule options to associate with this

rule node */

} RuleTreeNode;

RuleTreeNode中包含上述3个指针域,分别又能形成3个链表。RuleTreeNode*

类型的right指向下一个RuleTreeNode,相当于普通链表中的next域,只不过这里用right来命名。这样就形成了规则链表。

RuleFpList类的指针rule_func记录的是该规则的处理函数的链表。一条规则有时候需要调用多个处理函数来分析。所以,有必要做成链表。我们看看下面的

定义,除了next域,还有一个函数指针:

typedef struct _RuleFpList

{

/* rule check function pointer */

int (*RuleHeadFunc)(Packet *, struct _RuleTreeNode *, struct _RuleFpList *);

/* pointer to the next rule function node */

struct _RuleFpList *next;

} RuleFpList;

第3个指针域是OptTreeNode类的指针down,该行后面的注释说的很清楚,这是与这个规则节点相联系的规则选项的链表。很不幸,OptTreeNode的结构也相当复杂,而且又引出了几个新的链表。忽略一些域,OptTreeNode定义如下:

typedef struct _OptTreeNode

{

/* plugin/detection functions go here */

OptFpList *opt_func;

/* the ds_list is absolutely essential for the plugin system to work,

it allows the plugin authors to associate "dynamic" data structures

with the rule system, letting them link anything they can come up

with to the rules list */

void *ds_list[512]; /* list of plugin data struct pointers */

.......//省略了一些域

struct _OptTreeNode *next;

} OptTreeNode;

next指向链表的下一个节点,无需多说。OptFpList类型的指针opt_func指向选项函数链表,同前面说的RuleFpList没什么大差别。值得注意的是指针数组

ds_list,用来记录该条规则中涉及到的预定义处理过程。每个元素的类型是void*。在实际表示规则的时候,ds_list被强制转换成不同的预定义类型。

数字图像处理及matlab实现源代码【1】

% *-*--*-*-*-*-*-*-*-*-*-*-*图像处理*-*-*-*-*-*-*-*-*-*-*-* %{ % (一)图像文件的读/写 A=imread('drum.jpg'); % 读入图像 imshow(A); % 显示图像 imwrite(A,'drum.jpg'); info=imfinfo('drum.jpg') % 查询图像文件信息 % 用colorbar函数将颜色条添加到坐标轴对象中 RGB=imread('drum.jpg'); I=rgb2gray(RGB); % 把RGB图像转换成灰度图像 h=[1 2 1;0 0 0;-1 -2 -1]; I2=filter2(h,I); imshow(I2,[]); colorbar('vert') % 将颜色条添加到坐标轴对象中 % wrap函数将图像作为纹理进行映射 A=imread('4.jpg'); imshow(A); I=rgb2gray(RGB); [x,y,z]=sphere; warp(x,y,z,I); % 用warp函数将图像作为纹理进行映射 %} % subimage函数实现一个图形窗口中显示多幅图像 RGB=imread('drum.jpg'); I=rgb2gray(RGB); subplot(1,2,1); subimage(RGB); % subimage函数实现一个图形窗口中显示多幅图像subplot(1,2,2),subimage(I); % *-*--*-*-*-*-*-*-*-*-*-*-*图像处理*-*-*-*-*-*-*-*-*-*-*-* % (二)图像处理的基本操作 % ----------------图像代数运算------------------ %{ % imadd函数实现两幅图像的相加或给一幅图像加上一个常数 % 给图像每个像素都增加亮度 I=imread('4.jpg'); J=imadd(I,100); % 给图像增加亮度 subplot(1,2,1),imshow(I);title('原图'); subplot(1,2,2),imshow(J);title('增加亮度图'); % % imsubtract函数实现将一幅图像从另一个图像中减去或减去一个常数I=imread('drum.jpg'); J=imsubtract(I,100); % 给图像减去亮度 subplot(1,2,1),imshow(I);

spark+openfire 源代码部署

spark+openfire二次开发(一) 文章分类:Java编程 1.准备工作: 到官网上下载Openfire 3.6.4,并通过svn下载openfire、Spark和SparkWeb 的源代码 官网地址如下: https://www.wendangku.net/doc/6015360451.html,/downloads/index.jsp 注意官网上最新的Spark版本是2.5.8,其jdk环境最好使用1.6的版本。 2.环境搭建——spark源码安装配置 双击openfire_3_6_4.exe进行openfire的安装,安装过程很简单,不介绍了。 本例的开发环境是基于Eclipse的。 1)选择File——New——Project——Java Project。 输入项目工程名spark Contents中选择"Create project from existiing source",然后把spark 文件所在的文件夹加进去..

点击Finish。 2)生成Spark: 点击Window::Show View::Ant 右击Ant面板,选择Add Buildfiles 展开spark::build文件夹,选择build.xml,点击"OK" 在Ant面板,展开Spark,双击"release",等一段时间,会提示"Build Successful"。 3)运行Spark: 点击Run::Open Debug Dialog...,出现"Run"窗口 选择"Java Application",右键点击"New"按钮. 在"Main"标签页,将New_configuration换成Spark. 点击Project::Browse按钮,选择Spark,再点OK.

Apache_Spark源码走读系列篇二

超人学院—Apache Spark源码走读之Task运行期之函数调用关系分析 欢迎转载,转载请注明出处,超人学院。 概要 本篇主要阐述在TaskRunner中执行的task其业务逻辑是如何被调用到的,另外试图讲清楚运行着的task其输入的数据从哪获取,处理 的结果返回到哪里,如何返回。 准备 1.spark已经安装完毕 2.spark运行在local mode或local-cluster mode local-cluster mode local-cluster模式也称为伪分布式,可以使用如下指令运行 MASTER=local[1,2,1024] bin/spark-shell [1,2,1024]分别表示,executor number, core number和内存大小,其中内存大小不应小于默认的512M Driver Programme的初始化过程分析 初始化过程的涉及的主要源文件 1.SparkContext.scala 整个初始化过程的入口 2.SparkEnv.scala 创建BlockManager, MapOutputTrackerMaster, ConnectionManager, CacheManager 3.DAGScheduler.scala 任务提交的入口,即将Job 划分成各个stage的关键 4.TaskSchedulerImpl.scala 决定每个stage可以运行几个task, 每个task分别在哪个executor上运行 5.SchedulerBackend

1.最简单的单机运行模式的话,看LocalBackend.scala 2.如果是集群模式,看源文件 SparkDeploySchedulerBackend 初始化过程步骤详解 步骤1:根据初始化入参生成SparkConf,再根据SparkConf来创建SparkEnv, SparkEnv中主要包含以下关键性组件 1. BlockManager 2. MapOutputTracker 3. ShuffleFetcher 4. ConnectionManager private[spark] val env = SparkEnv.create( conf, "", conf.get("spark.driver.host"), conf.get("spark.driver.port").toInt, isDriver = true, isLocal = isLocal) SparkEnv.set(env) 步骤2:创建TaskScheduler,根据Spark的运行模式来选择相应的SchedulerBackend,同时启动taskscheduler,这一步至为关键 private[spark] var taskScheduler = SparkContext.createTaskScheduler(this, master, appName) taskScheduler.start() TaskScheduler.start目的是启动相应的SchedulerBackend,并启动定时器进行检测 overridedef start() { backend.start() if (!isLocal && conf.getBoolean("spark.speculation", false)) {

基于Spark的机器学习资料43、其它SparkML算法简单介绍

Spark ML算法简单介绍 一、线性回归算法 线性回归(Linear Regression),数理统计中回归分析,用来确定两种或两种以上变量间相互依赖的定量关系的一种统计分析方法,其表达形式为y = w'x+e,e为误差服从均值为0的正态分布,其中只有一个自变量的情况称为简单回归,多个自变量的情况叫多元回归。 这个例子中近简化使用房屋面积一个因子作为自变量,y轴对应其因变量房屋价格。所以我们机器学习的线性回归就变为对于给定有限的数据集,进行一元线性回归,即找到一个一次函数y=y(x) + e,使得y满足当x={2104, 1600, 2400, 1416, 3000, ... }, y={400, 330, 369, 232, 540, ... } 如下图所示: 至于公式的求解,大家可以自己去看一下源码或者方程求解,这里就不讲解了。 二、逻辑回归算法 logistic回归本质上是线性回归,只是在特征到结果的映射中加入了一层函数映射,即先把特征线性求和,然后使用函数g(z)将最为假设函数来预测。g(z)可以将连续值映射到0和1上。 它与线性回归的不同点在于:为了将线性回归输出的很大范围的数,例如从负无穷到正无穷,压缩到0和1之间,这样的输出值表达为“可能性”才能说服广大民众。当然了,把大值压缩到这个范围还有个很好的好处,就是可以消除特别冒尖的变量的影响。

三、贝叶斯分类算法 贝叶斯定理 贝叶斯定理解决的是这样一个问题:已知在事件B发生的条件下,事件A的发生概率P(A|B),怎样得到事件A发生的条件下,事件B的发生概率P(B|A)?贝叶斯定理为我们打通了从P(A|B) 到P(B|A) 的道路。 P(B|A) = P(A|B) ×P(B) / P(A) 举例说明,假设已经有了100个email,其中: 垃圾邮件占比60%,即P(Spam) = 0.6 80%的垃圾邮件包含关键字“buy”,即P(Buy|Spam) = 0.8 20%的垃圾邮件不包含关键字“buy” 正常邮件占比40%,即P(NotSpam) = 0.4 10%的正常邮件包含关键字“buy”,即P(Buy|NotSpam) = 0.1 90%的正常邮件不包含关键字“buy” 现在,第101个email 进来了,它包含关键字“buy”,那么它是垃圾邮件的概率P(Spam|Buy) 是多少? P(Spam|Buy) = P(Buy|Spam) ×P(Spam) / P(Buy) P(Buy) = P(Buy|Spam) ×P(Spam) + P(Buy|NotSpam) ×P(NotSpam) P(Spam|Buy) = (0.8 ×0.6) / (0.8 ×0.6 + 0.1 ×0.4) = 0.48 / 0.52 = 0.923 由此得出,这个email 有92.3%的可能是一个垃圾邮件。 四、SVM支持向量机算法 支持向量机是一个类分类器,它能够将不同类的样本在样本空间中践行分割,其中生成的分隔面叫作分隔超平面。给定一些标记好的训练样本,SVM算法输出一个最优化的分隔超平面。 五、决策树算法 决策树就是通过一系列规则对数据进行分类的一种算法,可以分为分类树和回归树两类,分类树处理离散变量的,回归树是处理连续变量。 样本一般都有很多个特征,有的特征对分类起很大的作用,有的特征对分类作用很小,甚至没有作用。如决定是否对一个人贷款是,这个人的信用记录、收入等就是主要的判断依据,而性别、婚姻状况等等就是次要的判断依据。决策树构建的过程,就是根据特征的决定性程度,先使用决定性程度高的特征分类,再使用决定性程度低的特征分类,这样构建出一棵倒立的树,就是我们需要的决策树模型,可以用来对数据进行分类。 决策树学习的过程可以分为三个步骤:1)特征选择,即从众多特征中选择出一个作为当前节点的分类标准; 2)决策树生成,从上到下构建节点;3)剪枝,为了预防和消除过拟合,需要对决策树剪枝。 六、Kmeans聚类算法 聚类(clustering)与分类(classification)的不同之处在于:分类是一种示例式的有监督学习算法,它要求必须事先明确知道各个类别的信息,并且断言所有待分类项都有一个类别与之对应,很多时候这个条件是不成立的,尤其是面对海量数据的时候;而聚类是一种观察式的无监督学习算法,在聚类之前可以不知道类别甚至不给定类别数量,由算法通过对样本数据的特征进行观察,然后进行相似度或相异度的分析,从而达到“物以类聚”的目的。 七、LDA主题模型算法 隐含狄利克雷分配(LDA,Latent Dirichlet Allocation)是一种主题模型(Topic Model,即从所收集的文档中推测主题)。甚至可以说LDA模型现在已经成为了主题建模中的一个标准,是实践中最成功的主题模型之一。 那么何谓“主题”呢?,就是诸如一篇文章、一段话、一个句子所表达的中心思想。不过从统计模型的角度来说,我们是用一个特定的词频分布来刻画主题的,并认为一篇文章、一段话、一个句子是从一个概率模型中生成的。也就是说在主题模型中,主题表现为一系列相关的单词,是这些单词的条件概率。形象来说,主题就是一个桶,里面装了出现概率较高的单词,这些单词与这个主题有很强的相关性。 LDA可以用来识别大规模文档集(document collection)或语料库(corpus)中潜藏的主题信息。它采用了词

数字图像处理matlab代码

一、编写程序完成不同滤波器的图像频域降噪和边缘增强的算法并进行比较,得出结论。 1、不同滤波器的频域降噪 1.1 理想低通滤波器(ILPF) I1=imread('eight.tif'); %读取图像 I2=im2double(I1); I3=imnoise(I2,'gaussian',0.01); I4=imnoise(I3,'salt & pepper',0.01); figure,subplot(1,3,1); imshow(I2) %显示灰度图像 title('原始图像'); %为图像添加标题 subplot(1,3,2); imshow(I4) %加入混合躁声后显示图像 title('加噪后的图像'); s=fftshift(fft2(I4)); %将灰度图像的二维不连续Fourier 变换的零频率成分 移到频谱的中心 [M,N]=size(s); %分别返回s的行数到M中,列数到N中n1=floor(M/2); %对M/2进行取整 n2=floor(N/2); %对N/2进行取整 d0=40; %初始化d0 for i=1:M for j=1:N d=sqrt((i-n1)^2+(j-n2)^2); %点(i,j)到傅立叶变换中心的距离 if d<=d0 %点(i,j)在通带内的情况 h=1; %通带变换函数 else %点(i,j)在阻带内的情况 h=0; %阻带变换函数 end s(i,j)=h*s(i,j); %ILPF滤波后的频域表示

end end s=ifftshift(s); %对s进行反FFT移动 s=im2uint8(real(ifft2(s))); %对s进行二维反离散的Fourier变换后,取复 数的实部转化为无符号8位整数 subplot(1,3,3); %创建图形图像对象 imshow(s); %显示ILPF滤波后的图像 title('ILPF滤波后的图像(d=40)'); 运行结果: 1.2 二阶巴特沃斯低通滤波器(BLPF) I1=imread('eight.tif'); %读取图像 I2=im2double(I1); I3=imnoise(I2,'gaussian',0.01); I4=imnoise(I3,'salt & pepper',0.01); figure,subplot(1,3,1); imshow(I2) %显示灰度图像 title('原始图像'); %为图像添加标题 subplot(1,3,2); imshow(I4) %加入混合躁声后显示图像 title('加噪后的图像'); s=fftshift(fft2(I4));%将灰度图像的二维不连续Fourier 变换的零频率成分 移到频谱的中心 [M,N]=size(s); %分别返回s的行数到M中,列数到N中n=2; %对n赋初值

Spark源码学习(4)——Scheduler

Spark源码学习(4)——Scheduler Scheduler的基本过程 用户提交的Job到DAGScheduler后,会封装成ActiveJob,同时启动JobWaiter监听作业的完成情况。同时依据job中RDD的dependency和dependency属性(窄依赖NarrowDependency,宽依赖ShufflerDependecy),DAGScheduler会根据依赖关系的先后产生出不同的stage DAG(result stage, shuffle map stage)。在每一个stage内部,根据stage产生出相应的task,包括ResultTask或是ShuffleMapTask,这些task会根据RDD中partition的数量和分布,产生出一组相应的task,并将其包装为TaskSet提交到TaskScheduler上去。 DAGScheduler DAGScheduler是高层级别的调度器。实现了stage-oriented调度。它计算一个DAG中stage 的工作。并将这些stage输出落地物化。 最终提交stage以taskSet方式提交给TaskScheduler。DAGScheduler需要接收上下层的消息,它也是一个actor。这里主要看看他的一些事件处理。以下是的所处理的事件。 private[scheduler] case class JobSubmitted( jobId: Int, finalRDD: RDD[_], func: (TaskContext, Iterator[_]) => _, partitions: Array[Int], callSite: CallSite, listener: JobListener, properties: Properties = null) extends DAGSchedulerEvent private[scheduler] case class StageCancelled(stageId: Int) extends DAGSchedulerEvent private[scheduler] case class JobCancelled(jobId: Int) extends DAGSchedulerEvent private[scheduler] case class JobGroupCancelled(groupId: String) extends DAGSchedulerEvent private[scheduler] case object AllJobsCancelled extends DAGSchedulerEvent private[scheduler] case class BeginEvent(task: Task[_], taskInfo: TaskInfo) extends DAGSchedulerEvent private[scheduler] case class GettingResultEvent(taskInfo: TaskInfo) extends DAGSchedulerEvent 还有很多,不一一罗列。

图像处理实例(含Matlab代码)

信号与系统实验报告——图像处理 学院:信息科学与工程学院 专业:2014级通信工程 组长:** 组员:** 2017.01.02

目录 目录 (2) 实验一图像一的细胞计数 (3) 一、实验内容及步骤 (3) 二、Matlab程序代码 (3) 三、数据及结果 (4) 实验二图像二的图形结构提取 (5) 一、实验内容及步骤 (5) 二、Matlab程序代码 (5) 三、数据及结果 (6) 实验三图像三的图形结构提取 (7) 一、实验内容及步骤 (7) 二、Matlab程序代码 (7) 三、数据及结果 (8) 实验四图像四的傅里叶变化及巴特沃斯低通滤波 (9) 一、实验内容及步骤 (9) 二、Matlab程序代码 (9) 三、数据及结果 (10) 实验五图像五的空间域滤波与频域滤波 (11) 一、实验内容及步骤 (11) 二、Matlab程序代码 (11) 三、数据及结果 (12)

实验一图像一的细胞计数 一、实验内容及步骤 将该图形进行一系列处理,计算得到途中清晰可见细胞的个数。 首先,由于原图为RGB三色图像处理起来较为麻烦,所以转为灰度图,再进行二值化化为黑白图像,得到二值化图像之后进行中值滤波得到细胞分布的初步图像,为了方便计数对图像取反,这时进行一次计数,发现得到的个数远远多于实际个数,这时在进行一次中值滤波,去掉一些不清晰的像素点,剩下的应该为较为清晰的细胞个数,再次计数得到大致结果。 二、Matlab程序代码 clear;close all; Image = imread('1.jpg'); figure,imshow(Image),title('原图'); Image=rgb2gray(Image); figure,imshow(Image),title('灰度图'); Theshold = graythresh(Image); Image_BW = im2bw(Image,Theshold); Reverse_Image_BW22=~Image_BW; figure,imshow(Image_BW),title('二值化图像'); Image_BW_medfilt= medfilt2(Image_BW,[3 3]); figure,imshow(Image_BW_medfilt),title('中值滤波后的二值化图像'); Reverse_Image_BW = ~Image_BW_medfilt; figure,imshow(Reverse_Image_BW),title('图象取反'); Image_BW_medfilt2= medfilt2(Reverse_Image_BW,[20 20]); figure,imshow(Image_BW_medfilt2),title('第二次中值滤波的二值化图像'); [Label, Number]=bwlabel(Image_BW_medfilt,8);Number [Label, Number]=bwlabel(Image_BW_medfilt2,8);Number

matlab数字图像处理源代码

数字图像去噪典型算法及matlab实现 希望得到大家的指点和帮助 图像去噪是数字图像处理中的重要环节和步骤。去噪效果的好坏直接影响 到后续的图像处理工作如图像分割、边缘检测等。图像信号在产生、传输过程中都可能会受到噪声的污染,一般数字图像系统中的常见噪声主要有:高斯噪声(主要由阻性元器件内部产生)、椒盐噪声(主要是图像切割引起的黑图像上的白点噪声或光电转换过程中产生的泊松噪声)等; 目前比较经典的图像去噪算法主要有以下三种: 均值滤波算法:也称线性滤波,主要思想为邻域平均法,即用几个像素灰度 的平均值来代替每个像素的灰度。有效抑制加性噪声,但容易引起图像模糊, 可以对其进行改进,主要避开对景物边缘的平滑处理。 中值滤波:基于排序统计理论的一种能有效抑制噪声的非线性平滑滤波信号处理技术。中值滤波的特点即是首先确定一个以某个像素为中心点的邻域,一般为方形邻域,也可以为圆形、十字形等等,然后将邻域中各像素的灰度值排序,取其中间值作为中心像素灰度的新值,这里领域被称为窗口,当窗口移动时,利用中值滤波可以对图像进行平滑处理。其算法简单,时间复杂度低,但其对点、线和尖顶多的图像不宜采用中值滤波。很容易自适应化。 Wiener维纳滤波:使原始图像和其恢复图像之间的均方误差最小的复原方法,是一种自适应滤波器,根据局部方差来调整滤波器效果。对于去除高斯噪声效果明显。 实验一:均值滤波对高斯噪声的效果 l=imread('C:\Documents and 桌面\1.gif');% 读取图像

J=imnoise(l,'gaussian',0,0.005);% 加入均值为0 ,方差为 0.005 的高斯噪声subplot(2,3,1);imshow(l); title(' 原始图像'); subplot(2,3,2); imshow(J); ti tle('加入高斯噪声之后的图像’); %采用MATLAB 中的函数filter2 对受噪声干扰的图像进行均值滤波 K1=filter2(fspecial('average',3),J)/255; % 模板尺寸为3 K2=filter2(fspecial('average',5),J)/255;% 模板尺寸为5 K3=filter2(fspecial('average',7),J)/255; % 模板尺寸为7 K4= filter2(fspecial('average',9),J)/255; % 模板尺寸为9 subplot(2,3,3);imshow(K1); ti tle(' 改进后的图像1'); subplot(2,3,4); imshow(K2); title(' 改进后的图像2'); subplot(2,3,5);imshow(K3); title(' 改进后的图像3'); subplot(2,3,6);imshow(K4); title(' 改进后的图像4');

Spark开发环境配置及流程(Intellij IDEA)

Spark开发环境配置及流程 之前已经将集群配置完成(详见Hadoop2.6.0搭建过程.doc和Spark1.2搭建过程.doc文档),开发环境中的JDK,Scala部分就不介绍了,下面直接介绍我们用的开发工具Interlij IDEA。为什么选择Intellij IDEA?因为它更好的支持Scala 项目,目前Spark开发团队使用它作为开发环境。 1.下载 直接到官方网站下载页面下载(https://www.wendangku.net/doc/6015360451.html,/idea/download/)。 有收费的完整版,也有免费的基本版本,收费的网上也有破解方案。 2.解压 解压到/usr/local,这是因为之前的Scala和Spark都放这里,也可以根据自己喜好。 [hadoop@lenovo0 Downloads]$ sudo tar -vxzf ideaIC-14.1.tar.gz -C /usr/local/ 改个名字,然后授权给hadoop用户。 [hadoop@lenovo0 local]$ cd /usr/local/ [hadoop@lenovo0 local]$ sudo mv ideaIC-14.1 ideaIC14 [hadoop@lenovo0 local]$ sudo chown -R hadoop:hadoop ideaIC14/ 3.启动 在解压的文件夹下有个文件介绍怎么打开应用,还有一些设置信息,大家可以看一看: 通过cat命令可以查看,我只截了一些关键的:

根据提示,我们直接进入到文件夹bin目录下执行./idea.sh即可启动: 之后便可以根据UI提示界面创建快捷方式,方便下次启动。 4.在IDEA中安装Scala插件 在IDEA的设置里面,直接搜索“plugins”,在右边的展开中搜索“scala”,点击相应的按钮添加插件即可: 5.配置Spark应用开发环境 这里以SparkPi程序为例子。 5.1创建Scala Project,设置名称,JDK和Scala路径:

regiongrow冈萨雷斯图像处理源代码

function [g,NR,SI,TI] = regiongrow(f,S,T) %REGIONGROW Perform segmentation by regin growing. % [g,NR,SI,TI] = REGIONGROW(F,S,T).S can be an array(the same size as F) % with a 1 at the coordinates of every seed point and 0s elsewhere.S can % also be a single seed value.Similarly,T can be an array(the same size % as F) containing a threshold value for each pixel in F.T can also be a % scalar,in which case it becomes a global threshold. % % On the output,G is the result of region growing,with each region % labeled by a different integer,NR is the number of regions,SI is the % final seed image used by the algorithm,and TI is the image consisting % of the pixels in F that satisfied the threshold test. f=double(f); %If S is a scalar,obtain the seed image. if numel(S)==1 SI=f==S; S1=S; else %S is an array.Eliminateduplicate,connected seed locations to reduce %the number of loop executions in the following sections of code. SI=bwmorph(3,'shrink',Inf); J=find(SI); S1=f(J);%array of seed value. end TI=false(size(f)); for K=1:length(S1) seedvalue=S1(K); S=abs(f-seedvalue)<=T; TI=TI|S; end %Use function imreconstruct with SI as the marker image to obtain the %regions corresponding to each seed in S.Functionbwlabel assigns a %different integer to each connected region. [g,NR]=bwlabel(imreconstruct(SI,TI)); end

spark-Bench环境搭建文档

Spark-Bench运行环境搭建 按照官方文档进行第3.1步系统环境配置的时候会出现几个错误,在这里一一解决 1、首先是wikixmlj的编译和安装问题,这个wikixmlj工程经过maven编译(即直接执行 mvn package命令,我觉得-Dmaven.test.skip=true应该是不需要的)后会在其target 目录下生产一个wikixmlj-1.0-SNAPSHOT.jar文件,接下来执行mvn install命令去安装这个jar包时就会报错。所以我通过以下命令手动安装jar的方式在maven的本地仓库中安装wikixmlj-1.0-SNAPSHOT.jar: mvn install:install-file -DgroupId=edu.jhu.nlp -DartifactId=wikixmlj

-Dversion=1.0-SNAPSHOT -Dpackaging=jar -Dfile=.\classes\artifacts\wikixmlj_.jar\wikixmlj.jar 注:因为在后面编译SparkBench工程中,需要依赖wikixmlj-1.0-SNAPSHOT.jar,所以必须在maven仓库中先安装这个jar包。而这个jar在网上是下载不到的,所以我只能把它github上的源码工程clone下来,然后再用idea编译,然后再打包jar包 2、第一步搞定后,在编译整个SparkBench工程(即直接在工程根目录执行./build-all.sh 命令)时也会出错,首先是在编译第一个子工程Common工程时出现问题: 其实这个问题是由于你的Spark-Bench工程是由jdk-1.8.0编译,而现在你本地只有jdk-1.7.0,所以就报了这个错,我通过将父工程的pom.xml文件中的jdk编译原版本和目标版本版本全部由1.8换成1.7后,这个问题得以解决。

最常用的matlab图像处理的源代码

最常用的一些图像处理Matlab源代 码 #1:数字图像矩阵数据的显示及其傅立叶变换 #2:二维离散余弦变换的图像压缩 #3:采用灰度变换的方法增强图像的对比度 #4:直方图均匀化 #5:模拟图像受高斯白噪声和椒盐噪声的影响 #6:采用二维中值滤波函数medfilt2对受椒盐噪声干扰的图像滤波 #7:采用MATLAB中的函数filter2对受噪声干扰的图像进行均值滤波 #8:图像的自适应魏纳滤波 #9:运用5种不同的梯度增强法进行图像锐化 #10:图像的高通滤波和掩模处理 #11:利用巴特沃斯(Butterworth)低通滤波器对受噪声干扰的图像进行平滑处理 #12:利用巴特沃斯(Butterworth)高通滤波器对受噪声干扰的图像进行平滑处理 1.数字图像矩阵数据的显示及其傅立叶变换 f=zeros(30,30); f(5:24,13:17)=1; imshow(f, 'notruesize'); F=fft2(f,256,256); % 快速傅立叶变换算法只能处矩阵维数为2的幂次,f矩阵不 % 是,通过对f矩阵进行零填充来调整 F2=fftshift(F); % 一般在计算图形函数的傅立叶变换时,坐标原点在 % 函数图形的中心位置处,而计算机在对图像执行傅立叶变换 % 时是以图像的左上角为坐标原点。所以使用函数fftshift进 %行修正,使变换后的直流分量位于图形的中心; figure,imshow(log(abs(F2)),[-1 5],'notruesize');

2 二维离散余弦变换的图像压缩I=imread('cameraman.tif'); % MATLAB自带的图像imshow(I); clear;close all I=imread('cameraman.tif'); imshow(I); I=im2double(I); T=dctmtx(8); B=blkproc(I,[8 8], 'P1*x*P2',T,T'); Mask=[1 1 1 1 0 0 0 0 1 1 1 0 0 0 0 0 1 1 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]; B2=blkproc(B,[8 8],'P1.*x',Mask); % 此处为点乘(.*) I2=blkproc(B2,[8 8], 'P1*x*P2',T',T); figure,imshow(I2); % 重建后的图像 3.采用灰度变换的方法增强图像的对比度I=imread('rice.tif'); imshow(I); figure,imhist(I); J=imadjust(I,[0.15 0.9], [0 1]); figure,imshow(J); figure,imhist(J);

数字图像处理代码大全

1.图像反转 MATLAB程序实现如下: I=imread('xian.bmp'); J=double(I); J=-J+(256-1); %图像反转线性变换 H=uint8(J); subplot(1,2,1),imshow(I); subplot(1,2,2),imshow(H); 2.灰度线性变换 MATLAB程序实现如下: I=imread('xian.bmp'); subplot(2,2,1),imshow(I); title('原始图像'); axis([50,250,50,200]); axis on; %显示坐标系 I1=rgb2gray(I); subplot(2,2,2),imshow(I1); title('灰度图像'); axis([50,250,50,200]); axis on; %显示坐标系 J=imadjust(I1,[0.1 0.5],[]); %局部拉伸,把[0.1 0.5]的灰度拉伸为[0 1]

subplot(2,2,3),imshow(J); title('线性变换图像[0.1 0.5]'); axis([50,250,50,200]); grid on; %显示网格线 axis on; %显示坐标系 K=imadjust(I1,[0.3 0.7],[]); %局部拉伸,把[0.3 0.7]的灰度拉伸为[0 1] subplot(2,2,4),imshow(K); title('线性变换图像[0.3 0.7]'); axis([50,250,50,200]); grid on; %显示网格线 axis on; %显示坐标系 3.非线性变换 MATLAB程序实现如下: I=imread('xian.bmp'); I1=rgb2gray(I); subplot(1,2,1),imshow(I1); title('灰度图像'); axis([50,250,50,200]); grid on; %显示网格线 axis on; %显示坐标系 J=double(I1);

Matlab图像处理入门到精通源代码

Matlab7.x图像处理 ch2_1_1:查看直方图(§2.1.3) I=imread('LENA256.bmp'); imshow(I); imhist(I) ch2_2_1:显示图像(§2.2.2) lena=imread('LENA256.bmp'); imshow(lena,256) ch2_3_1:添加颜色条(§2.3.1) %ìí?ó??é?ì? RGB = imread('saturn.png'); I = rgb2gray(RGB); h = [1 2 1; 0 0 0; -1 -2 -1]; I2 = filter2(h,I); imshow(I2,[]), colorbar('vert') ch2_3_2:图像的单帧显示(§2.3.2) %í???μ?μ¥????ê? %μ÷ó?catoˉêy??á?·ù?ò?èí???o?2¢3éò?????óDá???μ?í????óáD£?è?oó?ùμ÷ó?%imshowoˉêyà′??ê?μúò???í??? lena=imread('LENA256.bmp'); girl=imread('Girl.bmp'); A=cat(3, lena, girl); imshow(A(:,:,2)) ch2_3_3:图像的多帧显示(§2.3.2) %í???μ??à????ê? mri = uint8(zeros(128,128,1,27)); for frame=1:27 [mri(:,:,:,frame),map] = imread('mri.tif', frame); end montage(mri, map); ch2_3_4:图像的动画显示(§2.3.2) %í???μ??ˉ?-??ê? mri = uint8(zeros(128,128,1,27));

spark环境配置

一、安装JDK、Hadoop、 Spark、Scala等,搭建spark集群 环境:CentOS 6.4, Hadoop 1.1.2, JDK 1.7, Spark 0.7.2, Scala 2.9.3 折腾了几天,终于把Spark 集群安装成功了,其实比hadoop要简单很多,由于网上搜索到的博客大部分都还停留在需要依赖mesos的版本,走了不少弯路。 1. 安装 JDK 1.7 yum search openjdk-devel sudo yum install java-1.7.0-openjdk-devel.x86_64 /usr/sbin/alternatives --config java /usr/sbin/alternatives --config javac sudo vim /etc/profile # add the following lines at the end export JAVA_HOME=/usr/lib/jvm/java-1.7.0-openjdk-1.7.0.19.x86_64 export JRE_HOME=$JAVA_HOME/jre export PATH=$PATH:$JAVA_HOME/bin export CLASSPATH=.:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar # save and exit vim # make the bash profile take effect immediately $ source /etc/profile # test $ java -version 参考我的另一篇博客,安装和配置CentOS服务器的详细步骤。 2. 安装 Scala 2.9.3 Spark 0.7.2 依赖 Scala 2.9.3, 我们必须要安装Scala 2.9.3. 下载scala-2.9.3.tgz并保存到home目录. $ tar -zxf scala-2.9.3.tgz $ sudo mv scala-2.9.3 /usr/lib $ sudo vim /etc/profile

colorgrad(f, T)冈萨雷斯图像处理源代码

function [VG, A, PPG]= colorgrad(f, T) %COLORGRAD Computes the vector gradient of an RGB image. % [VG, VA, PPG] = COLORGRAD(F, T) computes the vector gradient, VG, % and corresponding angle array, VA, (in radians) of RGB image % F. It also computes PPG, the per-plane composite gradient % obtained by summing the 2-D gradients of the individual color % planes. Input T is a threshold in the range [0, 1]. If it is % included in the argument list, the values of VG and PPG are % thresholded by letting VG(x,y) = 0 for values <= T and VG(x,y) = % VG(x,y) otherwise. Similar comments apply to PPG. If T is not % included in the argument list then T is set to 0. Both output % gradients are scaled to the range [0, 1]. % Copyright 2002-2004 R. C. Gonzalez, R. E. Woods, & S. L. Eddins % Digital Image Processing Using MATLAB, Prentice-Hall, 2004 % $Revision: 1.6 $ $Date: 2003/11/21 14:27:21 $ if (ndims(f) ~= 3) | (size(f, 3) ~= 3) error('Input image must be RGB.'); end % Compute the x and y derivatives of the three component images % using Sobel operators. sh = fspecial('sobel'); sv = sh'; Rx = imfilter(double(f(:, :, 1)), sh, 'replicate'); Ry = imfilter(double(f(:, :, 1)), sv, 'replicate'); Gx = imfilter(double(f(:, :, 2)), sh, 'replicate'); Gy = imfilter(double(f(:, :, 2)), sv, 'replicate'); Bx = imfilter(double(f(:, :, 3)), sh, 'replicate'); By = imfilter(double(f(:, :, 3)), sv, 'replicate'); % Compute the parameters of the vector gradient. gxx = Rx.^2 + Gx.^2 + Bx.^2; gyy = Ry.^2 + Gy.^2 + By.^2; gxy = Rx.*Ry + Gx.*Gy + Bx.*By; A = 0.5*(atan(2*gxy./(gxx - gyy + eps))); G1 = 0.5*((gxx + gyy) + (gxx - gyy).*cos(2*A) + 2*gxy.*sin(2*A)); % Now repeat for angle + pi/2. Then select the maximum at each point. A = A + pi/2; G2 = 0.5*((gxx + gyy) + (gxx - gyy).*cos(2*A) + 2*gxy.*sin(2*A)); G1 = G1.^0.5; G2 = G2.^0.5; % Form VG by picking the maximum at each (x,y) and then scale % to the range [0, 1]. VG = mat2gray(max(G1, G2)); % Compute the per-plane gradients. RG = sqrt(Rx.^2 + Ry.^2); GG = sqrt(Gx.^2 + Gy.^2); BG = sqrt(Bx.^2 + By.^2); % Form the composite by adding the individual results and % scale to [0, 1]. PPG = mat2gray(RG + GG + BG);

相关文档
相关文档 最新文档