如何处理边缘情况:For 循环和模数

How to Deal with Edge Cases: For Loops and Modulo

我正在尝试对这样的图像应用简单的图像处理:我的 for 循环完全符合我的要求:它允许我找到最高强度的像素,并且还要记住那个像素的坐标。但是,只要遇到 rows 的倍数,代码就会中断——在本例中等于 18。

比如这张图片的长度(rows * columns of image)是414。所以程序失败的情况有414/18 = 23(即列数) . 也许有更好的方法来实现我的目标,但这是我能想到的按像素强度对图像进行排序同时还知道每个像素的坐标的唯一方法。很高兴接受替代代码的建议,但如果有人知道如何处理 mod(x,18) = 0 的情况(即,当向量的索引可被总行数整除时),那就太好了。

image = imread('test.tif');      % feed program an image
image_vector = image(:);         % vectorize image

[sortMax,sortIndex] = sort(image_vector, 'descend');   % sort vector so 
                              %that highest intensity pixels are at top
max_sort = [];
[rows,cols] = size(image);

for i=1:length(image_vector)
   x = mod(sortIndex(i,1),rows);         % retrieve original coordinates 
                                         % of pixels from matrix "image"
   y = floor(sortIndex(i,1)/rows) +1;
   if image(x,y) > 0.5 * max            % filter out background noise
      max_sort(i,:) = [x,y];
   else
      continue
   end
end

您知道 MATLAB 索引从 1 开始,因为您在计算 y 时执行 +1。但是你忘了先从索引中减去 1 。这是正确的计算:

index = sortIndex(i,1) - 1;
x = mod(index,rows) + 1;
y = floor(index/rows) + 1;

此计算由函数 ind2sub 执行,我建议您使用它。

编辑:实际上,ind2sub 相当于:

x = rem(sortIndex(i,1) - 1, rows) + 1;
y = (sortIndex(i,1) - x) / rows + 1;

(您可以通过键入 edit ind2sub 来查看。remmod 对于正输入是相同的,因此 x 的计算相同。但是对于计算 y 他们避免了 floor,我想它稍微更有效率。


另请注意

image(x,y)

相同
image(sortIndex(i,1))

即可以直接使用线性索引索引到二维数组中