[英]Correctly implementing a box resampling algorithm
我實現了一個重采樣算法,該算法可以與除盒形(最近鄰域)實現之外的所有其他方法配合使用,並且我一生無法弄清楚自己做錯了什么。 我有許多可行的示例(bicubic,lanczos,hermite,triangle等),因此我確定問題在特定實現中很簡單。
誰能看到我做錯了嗎?
可在此處找到我的重采樣器的完整源代碼以進行調試
這是我用於所有算法的大小調整方法:
protected override void Apply(ImageBase target, ImageBase source, Rectangle targetRectangle, Rectangle sourceRectangle, int startY, int endY)
{
int sourceWidth = source.Width;
int sourceHeight = source.Height;
int width = target.Width;
int height = target.Height;
int targetY = targetRectangle.Y;
int startX = targetRectangle.X;
int endX = targetRectangle.Right;
int right = (int)(this.Sampler.Radius + .5);
int left = -right;
// Scaling factors
double widthFactor = sourceWidth / (double)targetRectangle.Width;
double heightFactor = sourceHeight / (double)targetRectangle.Height;
// Width and height decreased by 1
int maxHeight = sourceHeight - 1;
int maxWidth = sourceWidth - 1;
for (int y = startY; y < endY; y++)
{
if (y >= 0 && y < height)
{
// Y coordinates of source points.
double originY = ((y - targetY) * heightFactor) - 0.5;
int originY1 = (int)originY;
double dy = originY - originY1;
// For each row.
for (int x = startX; x < endX; x++)
{
if (x >= 0 && x < width)
{
// X coordinates of source points.
double originX = ((x - startX) * widthFactor) - 0.5f;
int originX1 = (int)originX;
double dx = originX - originX1;
// Destination color components
double r = 0;
double g = 0;
double b = 0;
double a = 0;
for (int yy = left; yy <= right; yy++)
{
// Get Y cooefficient
double kernel1 = this.Sampler.GetValue(dy - yy);
if (Math.Abs(kernel1) < Epsilon)
{
continue;
}
int originY2 = originY1 + yy;
if (originY2 < 0)
{
originY2 = 0;
}
if (originY2 > maxHeight)
{
originY2 = maxHeight;
}
for (int xx = left; xx <= right; xx++)
{
// Get X cooefficient
double kernel2 = kernel1 * this.Sampler.GetValue(xx - dx);
if (Math.Abs(kernel2) < Epsilon)
{
continue;
}
int originX2 = originX1 + xx;
if (originX2 < 0)
{
originX2 = 0;
}
if (originX2 > maxWidth)
{
originX2 = maxWidth;
}
Bgra sourceColor = source[originX2, originY2];
r += kernel2 * sourceColor.R;
g += kernel2 * sourceColor.G;
b += kernel2 * sourceColor.B;
a += kernel2 * sourceColor.A;
}
}
Bgra destinationColor = new Bgra(b.ToByte(), g.ToByte(), r.ToByte(), a.ToByte());
target[x, y] = destinationColor;
}
}
}
}
}
這是可行的雙三次算法的實現,而無效的盒算法的實現。
雙三次
public class BicubicResampler : IResampler
{
/// <inheritdoc/>
public double Radius => 2;
/// <inheritdoc/>
public double GetValue(double x)
{
// The coefficient.
double a = -0.5;
if (x < 0)
{
x = -x;
}
double result = 0;
if (x <= 1)
{
result = (((1.5 * x) - 2.5) * x * x) + 1;
}
else if (x < 2)
{
result = (((((a * x) + 2.5) * x) - 4) * x) + 2;
}
return result;
}
}
框
public class BoxResampler : IResampler
{
/// <inheritdoc/>
public double Radius => 0.5;
/// <inheritdoc/>
public double GetValue(double x)
{
if (x < 0)
{
x = -x;
}
if (x <= 0.5)
{
return 1;
}
return 0;
}
}
雙三次輸出良好。
盒子少一點...
替換您的函數,該函數解析為return (x >= -0.5) && (x <= 0.5) ? 1 : 0
return (x >= -0.5) && (x <= 0.5) ? 1 : 0
return (x >= -0.5) && (x < 0.5) ? 1 : 0
return (x >= -0.5) && (x < 0.5) ? 1 : 0
可行嗎?
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.