1.函数句柄的创建

函数句柄(function handle)是MATLAB中的一类特殊的数据结构,它的地位类似于其它计算机语言里的函数对象(Javascript,Python),函数指针(C++),或者函数引用(Perl)。作用是将一个函数封装成一个变量,使其能够像其它变量一样在程序的不同部分传递。

MATLAB中的函数句柄在调用时和普通函数没有任何区别,下面展示几种创建函数句柄的方式,最后通过函数句柄调用sin(pi)。

% 函数句柄的创建% 方式1 : 直接加@
% 语法:@函数名fun1 = @sin; % 方式2 : str2func函数
% 语法:str2fun('函数名')
fun2 = str2func('cos'); % 方式3 : 匿名函数
% 语法:@(参数列表)单行表达式
fun3 = @(x, y)x.^2 + y.^2;  % 函数句柄的调用fun1(pi);

2.将函数句柄作为函数参数

函数对象的经典应用情境之一就是排序(Sorting),即为一列未知类型的数组提供自定义的排序规则。下面我将实现一个函数super_sort,接收两个参数,第一个参数为待排序的数组,第二个参数是一个对原始数据的变换函数。super_sort能够对原始数据按照变换后的结果进行排序,并返回排好序的原始数据。

%文件名:super_sort.m

function sorted = super_sort(arr, fh)
transformed = fh(arr);% 对原始数组进行变换
[~, index] = sort(transformed); % 获得排序后的原数组位置索引
sorted = arr(index); % 返回排序后的原数组
end

测试脚本:

arr = round(randn(8, 1) * 10);
super_sort(arr, @abs)
% 将arr按照其绝对值大小排序
super_sort(arr, @sin)
% 将arr按照sin(x)的结果排序

注意,与Perl或Python不同,这里提供的函数句柄并不用于元素间的比较,而是用于将数组内各个元素进行映射成待比较的值。

3.利用函数句柄进行画图

借助函数句柄,可以方便地画出各类函数的图像,这类绘图函数往往以ez开头,下面我将演示ezplot, ezsurf两个函数。

% ezplot画sin函数在[0, 2 * pi]内的曲线

ezplot(@sin, [0, 2 * pi]);

% ezplot利用x和y上的参数方程画心形线

xfun = @(t)3*(2*cos(t)-cos(2*t));
yfun = @(t)3*(2*sin(t)-sin(2*t));
ezplot(xfun, yfun);

% ezsurf画二次曲面

fun3 = @(x,y)x.^2+y.^2;
ezsurf(fun3, [-2, 2, -2, 2]);

4.利用函数句柄进行图像的滤波

MATLAB提供了colfilt这一函数,该函数能将图像分成独立的子块(局部处理),或者相互交叠的窗口(可实现二维卷积及中值滤波),并利用传入的函数句柄对各个子块进行处理。

函数原型为B = colfilt(A,[M N],BLOCK_TYPE,FUN),其中B是输出图像,A是输入图像,[M N]是图像块或窗口的长宽,BLOCK_TYPE参数决定是进行块处理还是窗口滑动处理,FUN就是处理用的函数句柄,它只接收一个矩阵参数,这个矩阵的每一列都是拉长为列向量的子图像,FUN一次可能要处理多个子图像。

下面将实现利用colfilt对图像进行5*5中值滤波,以及局部阈值化。

% 在BLOCK_TYPE=sliding时进行滑动窗口处理
% f的返回值必须是一个元素个数与输入矩阵的列数相等的行向量
% 行向量中每个元素都将作为对应窗口中心元素的输出值 I = imread('tire.tif');
f = @(mat)median(im2double(mat));
I2 = colfilt(I, [5
5], 'sliding', f);  % 在BLOCK_TYPE=distinct时进行子图像块的处理% f的返回值必须是和输入矩阵尺寸相同的矩阵
% 返回值中的每一列都将被复原成输出图像中的对应子块% 这里偷了一个懒, 直接将MATLAB自动分配的多个连续子图像
% 作为一个阈值化区域, 其实各个区域虽然连续,但大小是不相等的 thre = @(mat)im2bw(mat, graythresh(mat));
I3 = colfilt(I, [50
50], 'distinct', thre);
imshow([im2double(I) I2 I3]);

输出图像如下:

5.组合匿名函数实现更复杂的函数句柄

由于只能包含单行的表达式,匿名函数只能完成简单的运算。但是如果把多个匿名函数结合,就能实现更强大的功能。

当函数sort作用于矩阵时,将各列分别排序,如果要实现提取排序后第K小的行,使用单个匿名函会遇到麻烦。因为

@(mat)sort(mat)(K, :)

这样的语法在MATLAB中是错误的,通过组合匿名函数,我们就能解决这一问题。

extract_row = @(mat, k)mat(k, :);
order = @(mat, k)extract_row(sort(mat), k);

6.总结

函数句柄是函数的数据抽象,能够作为其它函数的参数。善用它,将让程序更加优雅并具有更强的灵活性。

MATLAB中的函数句柄及其应用的更多相关文章

  1. matlab中关于函数句柄、feval函数以及inline函数的解析 (转)

    http://blog.sina.com.cn/s/blog_7bff755b010180l3.html MATLAB函数句柄 函数句柄(Function handle)是MATLAB的一种数据类型. ...

  2. Matlab中的函数句柄@

    本系列文章由 @yhl_leo 出品,转载请注明出处. 文章链接: http://blog.csdn.net/yhl_leo/article/details/50699990 @是Matlab中的句柄 ...

  3. matlab中patch函数的用法

    http://blog.sina.com.cn/s/blog_707b64550100z1nz.html matlab中patch函数的用法——emily (2011-11-18 17:20:33) ...

  4. matlab中subplot函数的功能

    转载自http://wenku.baidu.com/link?url=UkbSbQd3cxpT7sFrDw7_BO8zJDCUvPKrmsrbITk-7n7fP8g0Vhvq3QTC0DrwwrXfa ...

  5. 【原创】Matlab中plot函数全功能解析

    [原创]Matlab中plot函数全功能解析 该帖由Matlab技术论(http://www.matlabsky.com)坛原创,更多精彩内容参见http://www.matlabsky.com 功能 ...

  6. Matlab中plot函数全功能解析

    Matlab中plot函数全功能解析 功能 二维曲线绘图 语法 plot(Y)plot(X1,Y1,...)plot(X1,Y1,LineSpec,...)plot(...,'PropertyName ...

  7. matlab 中max函数用法

    Matlab中max函数在矩阵中求函数大小的实例如下:(1)C = max(A)返回一个数组各不同维中的最大元素.如果A是一个向量,max(A)返回A中的最大元素.如果A是一个矩阵,max(A)将A的 ...

  8. matlab中cumsum函数

    matlab中cumsum函数通常用于计算一个数组各行的累加值.在matlab的命令窗口中输入doc cumsum或者help cumsum即可获得该函数的帮助信息. 格式一:B = cumsum(A ...

  9. 『转载』Matlab中fmincon函数获取乘子

    Matlab中fmincon函数获取乘子 一.输出结构 [x,fval,exitflag,output,lambda] = fmincon(......) 二.结构说明 lambda结构 说     ...

随机推荐

  1. 鬼知道NOI会不会成为下一个奥数

    认真写作文不可能的,这辈子不可能认真写作文的. (月考,期末考,高考即将到达战场,真香警告) 以下应该成为原稿!!! 真.喜欢写感悟,但我感觉我可能把它写的有点商业化,商业化的文章不可能放的,所以我尽 ...

  2. Android 中数据存储方式有哪些?

    a) 文件存储b) xml,SharedPreferencec) SQLite数据库d) ContentProvidere) 网络

  3. Linux-Ubuntu目录

    ubuntu没有盘符这个概念,只有一个根目录/,所有文件都在它下面 /:根目录,一般根目录下只存放目录,在Linux下有且只有一个根目录.所有的东西都是从这里开始.当你在终端里输入“/home”,你其 ...

  4. Amphorae 与 Octavia Worker 的安全通信实现

    前言 在前面的章节中我们记录了 LoadBalancer.Listener.Pool.Member 等等 Octavia 核心资源对象的创建流程,本篇我们在此之上继续讨论处于 LB Managemen ...

  5. Android SmartRefreshLayout 使用

    SmartRefreshLayout是一款实现上拉加载.下拉刷新的控件,网络上相关内容也很多,在这里简单总结下我的使用 使用SmartRefreshLayout需导入依赖:implementation ...

  6. 网易云课堂_C++程序设计入门(下)_第9单元:白公曾咏牡丹芳,一种鲜妍独“异常”_第9单元 - 作业5:OJ编程 - 使用异常进行图形类的错误处理

    第9单元 - 作业5:OJ编程 - 使用异常进行图形类的错误处理 查看帮助 返回   温馨提示: 1.本次作业属于Online Judge题目,提交后由系统即时判分. 2.学生可以在作业截止时间之前 ...

  7. 零填充(Zero-padding)

    零填充(Zero-padding):有时,在输入矩阵的边缘使用零值进行填充,这样我们就可以对输入图像矩阵的边缘进行滤波.零填充的一大好处是可以让我们控制特征图的大小.使用零填充的也叫做泛卷积,不适用零 ...

  8. Egret入门学习日记 --- 第七篇(书中 3.9节 内容)

    第七篇(书中 3.9节 内容) 好,今天就来看下 3.9节 的内容. 第一点: 昨天就已经搞定了. 第二点: 也包括在昨天的内容了. 第三点: 如果在构造函数里直接引用组件,就会挂掉. 但是把位置变化 ...

  9. Cocos2d-X网络编程(5) 使用Rapidjson解析数据

    Json基础及28种c++解析库性能对比 JSON 概念和特点:     JSON 指的是 JavaScript 对象表示法(JavaScript Object Notation)     JSON ...

  10. 安装 docker-registry-frontend

    拉取镜像  最新的V2 docker pull konradkleine/docker-registry-frontend:v2 创建 docker-compose.yml version: ' se ...