Image processing 加工中的高效裁剪计算
我正在处理中加载png。这个png在实际图像周围有很多未使用的像素。幸运的是,所有这些像素都是完全透明的。我的目标是裁剪png以仅显示图像,并去除未使用的像素。第一步是计算图像的边界。最初,我想检查每个像素的alpha值,看看该像素是边界的最高坐标还是最低坐标。像这样:Image processing 加工中的高效裁剪计算,image-processing,processing,crop,performance,Image Processing,Processing,Crop,Performance,我正在处理中加载png。这个png在实际图像周围有很多未使用的像素。幸运的是,所有这些像素都是完全透明的。我的目标是裁剪png以仅显示图像,并去除未使用的像素。第一步是计算图像的边界。最初,我想检查每个像素的alpha值,看看该像素是边界的最高坐标还是最低坐标。像这样: ------ ------ --->oo oooooo oooooo 然后我意识到我只需要在第一个非alpha像素之前这样做,然后在最高坐标范围内向后重复。像这样: ------ -->ooo oooooo ooo
------
------
--->oo
oooooo
oooooo
然后我意识到我只需要在第一个非alpha像素之前这样做,然后在最高坐标范围内向后重复。像这样:
------
-->ooo
oooooo
ooo<--
------
------
-->哦
呜呜
ooo=0;我——){//行
对于(inti2=gfx.height-1;i2>=0;i2--){//列
如果(alpha(gfx.pixels[(gfx.width*i2)+i])!=0){
_bounds.xMax=i;
_coordFound=true;
打破
}
}
如果(_coordFound){
打破
}
}
//y最小界
_coordFound=false;
对于(int i=0;i=0;i--){//列
对于(inti2=gfx.width-1;i2>=0;i2--){//行
如果(alpha(gfx.pixels[(gfx.width*i)+i2])!=0){
_bounds.yMax=i;
_coordFound=true;
打破
}
}
如果(_coordFound){
打破
}
}
返回_界;
}
无效cropImage(矩形边界){
PImage _temp=createImage((_-bounds.xMax-_-bounds.xMin)+1,(_-bounds.yMax-_-bounds.yMin)+1,ARGB);
_临时复制(gfx、_bounds.xMin、_bounds.yMin、(_bounds.xMax-_bounds.xMin)+1、(_bounds.yMax-_bounds.yMin)+1、0、0、_临时宽度、_临时高度);
gfx=_temp;//现在图像被裁剪
}
有没有更有效/更快的方法来计算图像的边界?
我仍然希望在计算过程中获得边界坐标,而不是仅仅切割图像。如果在变量中存储找到的最后一条完全空行,例如水平最小和最大扫描,您可以使用该选项将垂直扫描限制在尚未检查为空的区域,而不必扫描整列。根据可裁剪区域的数量和形状,可以为您节省大量资源-有关修改算法的视觉解释,请参见示意图:
顺便说一句,在你的
//x min界限
扫描中,你似乎在两个循环中迭代宽度,但是应该是一个循环中的高度?(当然,除非图像都是正方形:)如果在变量中存储最后一个找到的完全空行,例如水平最小和最大扫描,则可以使用该变量将垂直扫描限制为仅限于尚未检查为空的区域,而不必扫描整列。根据可裁剪区域的数量和形状,可以为您节省大量资源-有关修改算法的视觉解释,请参见示意图:
顺便说一句,在你的//x min界限
扫描中,你似乎在两个循环中迭代宽度,但是应该是一个循环中的高度?(当然,除非你的图像都是正方形:)我认为这篇文章在codereview.stackexchange.com上会更有效率。你想保留的图像部分中有透明像素吗?在你想要保留的图像中是否会有完整的透明像素行/列?这些图像平均有多大(宽*高)?我为其编写的程序使用40x40 png文件。用户可以在这些范围内自由绘制。当用户完成后,程序将把这些边界切割成一个较小的矩形。这些边界内的透明像素并不重要。我这样做是因为我想要更快/更好的性能,因此将png大小调整到最小将影响未来可能的计算。好的,我认为您的图像可能会大得多。40x40算不了什么。O(N^2)将很容易工作。我认为这篇文章在codereview.stackexchange.com上会更有效率。您希望保留的图像部分中有透明像素吗?在你想要保留的图像中是否会有完整的透明像素行/列?这些图像平均有多大(宽*高)?我为其编写的程序使用40x40 png文件。用户可以在这些范围内自由绘制。当用户完成后,程序将把这些边界切割成一个较小的矩形。这些边界内的透明像素并不重要。我这样做是因为我想要更快/更好的性能,因此将png大小调整到最小将影响未来可能的计算。好的,我认为您的图像可能会大得多。40x40算不了什么。O(N^2)将很容易工作。我确实使用了方形图像,但在这样做时没有注意到这个错误。我现在修复了它,谢谢。我确实使用了方形图像,这样做没有注意到这个错误。我现在修好了,谢谢。
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
}