zoukankan      html  css  js  c++  java
  • MATLAB中的函数句柄及其应用

    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.总结

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

  • 相关阅读:
    redis搭建集群并用TreeSoft管理
    使用windows任务计划程序自动清除C盘缓存文件
    深入理解JavaScript事件循环机制
    redux源码解读(二)
    redux源码解读(一)
    create-react-app源码解读之为什么不搞个山寨版的create-react-app呢?
    深入理解CSS系列(二):为什么height:100%不生效?
    深入理解CSS系列(一):理解CSS的盒子模型
    搭建一个交互式的前端构建环境.md
    实习这件小事(一位大四狗的前端实习经历)
  • 原文地址:https://www.cnblogs.com/heleifz/p/matlab-function-handle.html
Copyright © 2011-2022 走看看