如何以最少的for循环遍历像素块

时间:2019-08-31 10:58:25

标签: c for-loop image-processing

我有一个宽*高像素的图像,我想在其中循环遍历像素块,比如说块大小为10 *10。我如何用最少的循环次数来做到这一点?

我尝试过首先遍历每一列,然后遍历每一行,并从这两个外部循环中获取x和y的起始位置。然后循环从块的起始位置开始循环,直到块大小并处理像素。这消耗了四个嵌套循环。

for (int i = 0; i < Width; i+=Block_Size) {

 for (int j = 0; j < Height; j+=Block_Size) {

   for (int x = i; x < i + Block_Size; x++) {

      for (int y = j; y < j + Block_Size; y++) {                     

        //Get pixel values within the block

       }

     }

   }

 }

2 个答案:

答案 0 :(得分:1)

  

如何用最少的循环次数做到这一点?

您可以通过完全展开任意数量的循环级别来减少循环次数。对于固定的栅格尺寸,您可以将它们全部展开,从而产生一个零循环的(可能很长的)实现。对于已知的Block_Size,无论整体尺寸是否已知,您都可以展开一个或两个内部循环,仅剩下两个循环。

但是您为什么要考虑这样的事情?问题似乎是假设减少循环嵌套的深度会有某种内在的优势,但这并不一定是正确的,而且可能产生的影响很小。

我倾向于猜测您已经研究了一些计算复杂性理论,并且摒弃了深层循环嵌套必然导致伸缩性差的性能,甚至深层循环嵌套本质上具有较差的性能周期的想法。这些是误解,尽管相对普遍,但反过来还是要反过来看问题。

关于循环嵌套的性能如何缩放的主要考虑因素是最里面的循环的主体有多少次,

        //Get pixel values within the block

被执行。对于任何合理的方法,无论涉及多少循环,您都将获得对光栅中每个像素精确执行一次的合理方法的性能大致相同。在这种情况下,代码清晰应该是您的目标,并且原始的四循环嵌套非常清晰。

答案 1 :(得分:0)

可以通过三个循环来实现此目的,但是要做到这一点,您将需要存储有关每个像素块从何处开始以及总共有多少像素块的信息!
与此无关,图像的宽度和高度都必须是Block_Size的倍数。

这是通过三个循环实现的可能性:

int numberOfBlocks = x;
int pixelBlockStartingPoints[numberOfBlocks] = { startingPoint1, startingPoint2, ... };

for(int i = 0; i < numberOfBlocks; i++){
    for(int j = pixelBlockStartingPoints[i]; j < pixelBlockStartingPoint[i] + Block_Size; j++){
        for(int k = pixelBlockStartingPoints[i]; k < pixelBlockStartingPoint[i] + Block_Size; k++){
            // Get Pixel-Data
        }
    }
}