计算一个区域内或外的邻域

4
我在MATLAB中遇到了一个问题:
假设我有一个如下所示的矩阵。我想要做的是计算黄色像素的平均值。(答案为108) enter image description here 如果给出的选项是outside,则可以进行如下计算。
另一方面,如果选项是inside,则需要执行如下操作。 enter image description here **我想编写一个算法来查找标有零的区域内或外的平均值,具体取决于手动设置的选项。** 可以考虑**4邻域**或8邻域。我想在MATLAB中计算这个。你们能帮我吗?

提示:对矩阵进行二值化处理,然后使用 bwtraceboundary 函数查找相关像素。 - bla
@natan,您能具体说明一下吗? - roni
2个回答

5

% 首先,创建图像

FirstImage = [
108 113 121 129 128 124 117 101
114 76  60  110 98  74  121 109
114 62  52  105 85  59  121 116
110 59  54  104 0   0   0   115
104 55  54  104 0   0   0   113
96  48  51  105 0   0   0   113
94  60  69  115 0   0   0   110
99  108 122 130 135 0   0   109
];

SecondImage = [
0   0   0   0   0   0
138 137 137 137 0   0
138 127 129 135 138 0
132 97  99  133 135 0
134 108 110 137 137 0
141 140 140 140 139 0
138 138 138 140 0   0
0   0   0   0   0   0
];

%将图像二值化并反转,使图像中的零变成1。
%这是为了与 bwtraceboundary 兼容

im = FirstImage == 0 ;

% 找到对象坐标以满足 bwtraceboundary 的要求

objectCoord = find(im); 
[startRow,startCol]  = ind2sub(size(im),objectCoord(1) );  

%find()函数按列扫描矩阵,因此我们知道它将从左上角开始,并逐列向下工作。因此,边界的某些部分必须位于找到的第一个坐标东侧。这是确定起始坐标的一种方法。

contour = bwtraceboundary(im,[startRow startCol],'E' ); 

% 标记轮廓

contourimage = zeros(size(im));
contourind = sub2ind(size(contourimage),contour(:,1),contour(:,2))
contourimage(contourind) = 1;



contourimage =

  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     1     1     1     0
  0     0     0     0     1     0     1     0
  0     0     0     0     1     0     1     0
  0     0     0     0     1     0     1     0
  0     0     0     0     0     1     1     0


% 现在,这只会检测对象本身的边界。
% 我们正在寻找最近的非零值接近边界。
% 要获取最近的非零值,
% 对轮廓图像应用膨胀
% 然��将其与原始图像逐元素相乘。
% 计算非零值的平均值。


% 进行膨胀操作

mask = bwmorph(contourimage,'dilate')

mask =

 0     0     0     0     0     0     0     0
 0     0     0     0     0     0     0     0
 0     0     0     1     1     1     1     1
 0     0     0     1     1     1     1     1
 0     0     0     1     1     1     1     1
 0     0     0     1     1     1     1     1
 0     0     0     1     1     1     1     1
 0     0     0     1     1     1     1     1



% 将原始图像与mask逐元素相乘。
% 对象本身将被清零,非零边界将保留。

A=mask.*FirstImage

A =

 0     0     0     0     0     0     0     0
 0     0     0     0     0     0     0     0
 0     0     0   105    85    59   121   116
 0     0     0   104     0     0     0   115
 0     0     0   104     0     0     0   113
 0     0     0   105     0     0     0   113
 0     0     0   115     0     0     0   110
 0     0     0   130   135     0     0   109



% 然后计算平均值

mean(A(A>0))

ans =

108.6875

没错,就是这样...我让你的代码更加简洁了,你得到了我的赞成。 - bla
嗨,我尝试运行这个程序,但在bwtraceboundary命令中出现了错误。它显示“使用bwtraceboundary时出错,期望输入参数2 P 为向量”。我已经重新检查了代码,看起来是正确的。有人能告诉我为什么会出现这个错误吗? - roni
当我运行它时,它对我有效。请检查startRow和startCol是否是相同大小的向量。我现在手头没有Matlab,所以无法检查它。 - kkuilla
你可以尝试这个: objectCoordinates = find(im>0); [startRow,startCol] = ind2sub(size(im), objectCoordinates(1)); contour = bwtraceboundary(im, [startRow startCol], 'E'); - kkuilla

2
另一种解决方案: 使用以下任一方法:
BW = ~(FirstImage>0);

或者:

BW = SecondImage>0;

然后:

[B,L] = bwboundaries(BW,'noholes');
B=cell2mat(B);
m=zeros(size(BW));
m(sub2ind(size(BW),B(:,1),B(:,2)))=1

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接