首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >如何在matlab编程中逢山开路、遇水搭桥?

如何在matlab编程中逢山开路、遇水搭桥?

作者头像
巴山学长
发布2020-02-17 15:04:46
9220
发布2020-02-17 15:04:46
举报
文章被收录于专栏:巴山学长巴山学长

Error! Error! Error!

相信小伙伴们在matlab编程中肯定最不愿意遇见的就是“Error”了吧,前几天帮忙一位小伙伴写代码,其中需要使用到一个圆形区域去逐行扫描矩阵,以确定每个矩阵元周围元素的分布情况。

要处理这个问题,边界问题肯定是不可能避免的,比如在矩阵四角处,其周围元素只有四分之一圆的区域,在四条矩阵边上,都是不是一个完整的圆。如果直接用矩阵位置索引来进行相关计算,边界区域必然会出现小于或等于0以及大于矩阵本身大小的索引值,若不进行妥善处理,就会出现久违的“Error”。

今天就给介绍一个函数组合套件。用了它,今后在处理类似问题时就可以不用顾虑索引值越界问题而随心所欲地写程序,烦人的“Error”提示信息也将一去不复返,这个函数就是try...catch...end

咱公众号在很久以前的一篇推文中有介绍过try...catch...end语句(matlab流程控制(二)),其主要作用是执行语句并捕获产生的错误,而不致使程序因出现未知错误而停止运行,相当于是if...else...end语句的升级版。

其运行流程如下图所示 (注:try所在行后面不需要任何判断条件,catch部分可以不用添加):

在程序执行过程中,如果 try 块中的语句没有任何错误,则按绿色虚线流程运行。如果 try 块中的任何语句发生错误,则走红色虚线流程并在 catch 块中捕获产生的错误,进而按蓝色虚线流程执行catch块,最后出end。

下面就以圆形区域逐行扫描矩阵来说明如何在应用过程中巧妙地使用try...catch...end语句来让程序即使遇到错误也能够照常运行下去。

示例处理规则如下:对于一张灰度图,用圆型区域逐点扫描灰度图中的像素,如果圆形区域里的所有其他像素点灰度值的平均值大于当前像素点, 则当前像素点灰度值修改为为:min([round(1.2*当前灰度值),255];如果小于当前像素点值,则当前像素点值修改为为:max([0,round(0.8*当前灰度值)](注:这里仅是为了说明try...catch...end语句在程序出错的情况下的应用,该处理方式并无任何实际意义)。

clc;clear;close all;
I = imread('lenna.png');
% 修改图像尺寸
nI = imresize(I,[100 100]); 
% 转换成灰度图
gI = rgb2gray(nI);
tgI = gI;
% 强制类型转换以便后续计算
dI = double(gI);
[mm,nn] = size(gI);
% 定义扫描圆半径r
r = 3;
for m = 1:mm
    for n = 1:nn
        re = calcN(dI,m,n,mm,nn,r);
        if re > dI(m,n)
            tgI(m,n) = uint8(1.1*gI(m,n));
        else
            tgI(m,n) = uint8(0.9*gI(m,n));
        end
           
    end
end
figure('color','w');
subplot(1,3,1);imshow(nI);title('原始缩小图');
subplot(1,3,2);imshow(gI);title('灰度图');
subplot(1,3,3);imshow(tgI);title('处理图');

calcN函数:

function re = calcN(I,M,N,mm,nn,R)
re = 0;
k = 0;
for m = M-R:M+R
    for n = N-R:N+R
        try
        % 索引值小于等于0,或者越界时,程序都将出错
        % 这里使用try...catch...end巧妙避开了错误索引,
        % 而只计算矩阵大小范围内索引值,比使用if语句更简洁
            tmp = I(m,n);
            tR = norm([M,N]-[m,n]);
            if tR < R && m ~= mm && n ~= nn
                k = k + 1;
                re = re+tmp;
            end
        catch
            disp('当前索引值越界');
        end
    end
end
re = re/k;

下图是索引值越界时的运行流程(两个断点时)和在正常范围的运行流程(一个断点时)的单步调试图,和上面的流程线路图完全一样。

处理效果对比图

望小伙伴们细细品味上面的代码,然后举一反三,只要try...catch...end语句使用得当,在“错误(有bug)”的程序中照样能够运行出正确的结果。由于相关程序已经全部给出,这里就不打包了。运行前只要随便找一张图片替换程序中的所用图片就能正常运行了。

参考资料:

https://ww2.mathworks.cn/help/matlab/ref/try.html

素材来源:https://en.wikipedia.org/wiki/Lena_Forsén

图片来源:由 bashan 设计制作,如要使用请联系matlab爱好者公众号授权。

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2020-01-14,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 巴山学长 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档