我正在尝试创建一个Java函数,通过将像素移动到图像的相对中心来对图像产生凸出效果。我首先取像素的(x,y)坐标,找到相对位移,x = x-(x / 2)并将其转换为极坐标形式[r cos(a),r sin (一个)]。 r由下式找到:r = Math.sqrt(x x + y y)。使用Math.atan2(y / x)找到角度a。使用r'= 2r ^ 1.5找到新的半径(r')。但是,来自[r cos(a),r sin(a)]的新x,y值超出了图像的尺寸,并且出现错误。
我犯了一个根本性的错误吗?
public void bulge()
{
double xval, yval = 0;
//loop through the columns
for(int x = 0; x < this.getWidth(); x++)
{
//loop through the rows
for(int y = 0; y < this.getHeight(); y++)
{
int redValue, greenValue, blueValue = 0;
double newRadius = 0;
Pixel pixel = this.getPixel(x,y);
redValue = pixel.getRed();
greenValue = pixel.getGreen();
blueValue = pixel.getBlue();
xval = x - (x/2);
yval = y - (y/2);
double radius = Math.sqrt(xval*xval + yval*yval);
double angle = Math.atan2(yval, xval);
newRadius = 2*(Math.pow(radius,1.5));
xval = (int)(newRadius*Math.sin(angle));
yval = (int)(newRadius*Math.cos(angle));
Pixel pixelNewPos = this.getPixel((int)xval, (int)yval);
pixelNewPos.setColor(new Color(redValue, greenValue, blueValue));
}
}
}
答案 0 :(得分:0)
我犯了一个根本性的错误吗?
在概念层面,是的。您的算法采用矩形图像并移动像素的位置以提供更大的非直视图像。显然,它不适合您的原始矩形。
因此,您需要剪切(即丢弃)落在矩形之外的像素,或者您需要使用更大的矩形,以便所有映射的像素都落在其中。
在后一种情况下,边缘会有间隙......如果你的转型正在做你声称它做的事情。矩形的非线性变换不会有直边。
答案 1 :(得分:0)
通过从图像B中的像素到图像A中的像素的反向变换,成功地将源图像A的变换应用到目标图像B要容易得多。
这意味着对于目标图像B中的每个像素,确定源图像A中对颜色有贡献的一个或多个像素。这样你就不会在目标图像中找到一堆未被触摸的像素。
作为使用2的线性缩放操作的示例,一个简单的实现可能如下所示:
for (int x = 0; x < sourceWidth; ++x) {
for (int y = 0; y < sourceHeight; ++y) {
Pixel sourcePixel = sourceImage.getPixel(x, y);
int destPixelX = x * 2;
int destPixelY = y * 2;
destImage.setPixel(destPixelX, destPixelY, sourcePixel);
}
}
从该代码中可以清楚地看出,目标图像中不会设置具有奇数X或Y值的像素。
更好的方法是这样的:
for (int x = 0; x < destWidth; ++x) {
for (int y = 0; y < destHeight; ++y) {
int sourcePixelX = x / 2;
int sourcePixelY = y / 2;
Pixel sourcePixel = sourceImage.getPixel(sourcePixelX, sourcePixelY);
destImage.setPixel(x, y, sourcePixel);
}
}
虽然这通常不是一个好的图像放大算法,但它确实显示了如何确保目标图像中的所有像素都已设置。