加工中的有效裁剪计算

时间:2013-07-25 18:23:27

标签: image-processing processing crop performance

我正在加载png。这个png在实际图像周围有很多未使用的像素。幸运的是,所有这些像素都是完全透明的。我的目标是裁剪png只显示图像并摆脱未使用的像素。第一步是计算图像的边界。最初我想检查每个像素的alpha值,看看该像素是否是边界的最高或最低坐标。像这样:

------
------
--->oo
oooooo
oooooo

然后我意识到我只需要这样做直到第一个非alpha像素并向后重复它以获得最高坐标界限。像这样:

------
-->ooo
oooooo
ooo<--
------

这意味着对相同结果的计算量减少。然而,我从中获得的代码似乎仍然非常复杂。这是:

class Rect {  //class for storing the boundries
  int xMin, xMax, yMin, yMax;
  Rect() {

  }
}

PImage gfx;

void setup() {
  size(800, 600);
  gfx = loadImage("resources/test.png");
  Rect _bounds = calcBounds();  //first calculate the boundries
  cropImage(_bounds);  //then crop the image using those boundries
}

void draw() {

}

Rect calcBounds() {
  Rect _bounds = new Rect();
  boolean _coordFound = false;
  gfx.loadPixels();

  //x min bounds
  for (int i = 0; i < gfx.width; i++) {  //rows
    for (int i2 = 0; i2 < gfx.height; i2++) {  //columns
      if (alpha(gfx.pixels[(gfx.width * i2) + i]) != 0) {
        _bounds.xMin = i;
        _coordFound = true;
        break;
      }
    }
    if (_coordFound) { 
      break;
    }
  }

  //x max bounds
  _coordFound = false;
  for (int i = gfx.width - 1; i >= 0; i--) {  //rows
    for (int i2 = gfx.height - 1; i2 >= 0; i2--) {  //columns
      if (alpha(gfx.pixels[(gfx.width * i2) + i]) != 0) {
        _bounds.xMax = i;
        _coordFound = true;
        break;
      }
    }
    if (_coordFound) { 
      break;
    }
  }

  //y min bounds
  _coordFound = false;
  for (int i = 0; i < gfx.height; i++) {  //columns
    for (int i2 = 0; i2 < gfx.width; i2++) {  //rows
      if (alpha(gfx.pixels[(gfx.width * i) + i2]) != 0) {
        _bounds.yMin = i;
        _coordFound = true;
        break;
      }
    }
    if (_coordFound) { 
      break;
    }
  }

  //y max bounds
  _coordFound = false;
  for (int i = gfx.height - 1; i >= 0; i--) {  //columns
    for (int i2 = gfx.width -1; i2 >= 0; i2--) {  //rows
      if (alpha(gfx.pixels[(gfx.width * i) + i2]) != 0) {
        _bounds.yMax = i;
        _coordFound = true;
        break;
      }
    }
    if (_coordFound) { 
      break;
    }
  }

  return _bounds;
}

void cropImage(Rect _bounds) {
  PImage _temp = createImage((_bounds.xMax - _bounds.xMin) + 1, (_bounds.yMax - _bounds.yMin) + 1, ARGB);
  _temp.copy(gfx, _bounds.xMin, _bounds.yMin, (_bounds.xMax - _bounds.xMin) + 1, (_bounds.yMax - _bounds.yMin)+ 1, 0, 0, _temp.width, _temp.height);
  gfx = _temp;  //now the image is cropped
}

有没有更有效/更快的方法来计算图像的边界? 而且我仍然希望之后的边界坐标,而不是在计算过程中切掉图像。

1 个答案:

答案 0 :(得分:1)

如果您存储最后一个完全空行,例如变量中的水平最小和最大扫描,您可以使用它将垂直扫描限制为尚未检查为空的区域,而不必扫描完整列。根据可以为您节省很多时间的可裁剪区域的数量和形状 - 请参阅原理图以获得修改算法的直观说明:

Optimization schematic


顺便说一下,在你的//x min bounds扫描中,你似乎在两个for循环中迭代宽度,但是应该是一个高度吗? (除非你的图像当然都是正方形的:))