Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/image-processing/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Image processing 这种用于图像缩放的最近邻算法有什么问题?_Image Processing_Rust_Nearest Neighbor - Fatal编程技术网

Image processing 这种用于图像缩放的最近邻算法有什么问题?

Image processing 这种用于图像缩放的最近邻算法有什么问题?,image-processing,rust,nearest-neighbor,Image Processing,Rust,Nearest Neighbor,我已经蹲了好几天,试图找出最近邻插值在缩放一半大小的图像时有什么问题。我使用的是Rust,但我认为它没有算法那么重要: /// Interpolate using nearest neighbor. pub fn nearest(mut src: &mut Image, w2: i32, h2: i32) -> RasterResult<()> { // Compute scale let x_scale: f64 = src.width as f64

我已经蹲了好几天,试图找出最近邻插值在缩放一半大小的图像时有什么问题。我使用的是Rust,但我认为它没有算法那么重要:

/// Interpolate using nearest neighbor.
pub fn nearest(mut src: &mut Image, w2: i32, h2: i32) -> RasterResult<()> {

    // Compute scale
    let x_scale: f64 = src.width as f64 / w2 as f64;
    let y_scale: f64 = src.height as f64 / h2 as f64;

    // Create destination image
    let mut dest = Image::blank(w2, h2);

    // Loop thru destination image's pixels
    for y2 in 0..h2 {
        for x2 in 0..w2 {

            // Get location from src using nearest neighbor
            let x1: i32 = ( x2 as f64 * x_scale ).floor() as i32;
            let y1: i32 = ( y2 as f64 * y_scale ).floor() as i32;
            let pixel = try!(src.get_pixel(x1, y1));

            // Apply the pixels
            try!(dest.set_pixel(x2, y2, pixel));
        }
    }

    // Update the source image
    src.width = dest.width;
    src.height = dest.height;
    src.bytes = dest.bytes;

    Ok(())
}
它适用于常规图像,但不适用于特殊情况。 以下是测试图像:

用我的代码缩放到一半:

以下是Photoshop的:

我用GD进行了测试,结果与Photoshop相似

我的调查使我认为,与其他像素(绿色方块)相比,我对源像素(红色方块)的计算减少了一个:

我也试着寻找线索,但我不完全理解它的作用

为了澄清,我不是说使用不同的插值方法,例如双线性和双三次插值。我正在将我的最近邻算法及其结果与Photoshop和GD的最近邻算法的结果进行比较。我不是问为什么我在Photoshop中的结果很难看,因为我使用了最近邻算法


(测试图像由Jonas Berlin via提供)

执行最近邻插值的更好方法是使插值越过目标像素的中心,而不是其左上角。在代码中,这意味着在计算
x1
y1
时,将
0.5
添加到
x2
y2

let x1: i32 = ( (x2 as f64 + 0.5) * x_scale ).floor() as i32;
let y1: i32 = ( (y2 as f64 + 0.5) * y_scale ).floor() as i32;
当您按1/2缩放时,这并不一定会产生更好的结果:每个目标像素都是从2x2源区域中选择的,因此选择哪个源像素并不重要。但当按1/3缩放时,这意味着您选择3x3区域的中心,而不是左上角,这会更好

Photoshop可能会使用这样的方法,这就是为什么会看到不同的结果


请注意,即使这使测试图像的缩放效果更好,也可以生成另一个使用新算法看起来不好的测试图像。将测试图像偏移(1,1)可能就可以了。

您的算法肯定没有错。这取决于您选择如何定义坐标。所请求的缩放是图像分辨率的一半,这意味着每个目标像素需要考虑四个像素;它们是等距的,覆盖了每个目标像素的四分之一,所以“最近的”不是一个有用的选择指标。即使选择是每像素随机的,您仍然可以声明最近邻,但这将是一个糟糕的实现,因为它将使用噪声分布

本例中的图像旨在展示实际做出的选择。一些重缩放程序做出了显著的选择,特别是某些版本的Microsoft Internet Explorer,这可能会导致奇怪的偏见

例如,在VIP中,如果我对图像应用最近邻缩小,我会得到你的结果(偏向较暗的像素),但如果我先应用一个像素的对角线偏移(通过选择奇数偏移区域),我会得到Photoshop结果(偏向较亮的像素)。这仅仅是向上或向下舍入0.5的结果。通过定义子像素坐标的位置,也就是说,如果给定像素的坐标位于该像素的角点或中心,则可以获得更准确的结果


该图像的设计似乎不是为了测试最近邻,而是为了测试线性插值的伽马计算。许多图像定标器错误地假设颜色空间是线性的,可以使用像素值的直线平均值,但我们的视觉大致是对数的,因此像sRGB这样流行的颜色空间使用伽马曲线来更好地逼近它

您使用了一个测试图像,旨在表明简单的缩放算法(如最近邻)是不够的。事实证明了这一点。一切都按计划进行。如果你想得到更好的结果,请使用更好的缩放算法。@interjay-不,我想你误解了这个问题。我在Photoshop和GD中使用了最近邻算法,结果与我的最近邻算法不同。我不是要求使用不同的插值方法。我希望该算法与其他图像处理程序类似,最好使用photoshop和imagemagick。这并不让用户感到惊讶,因为结果与其他LIB不同。是的,测试图像是针对gamma的,但我选择在这里使用它,因为它可以很好地突出这个微妙的问题。谢谢你的回复。
let x1: i32 = ( (x2 as f64 + 0.5) * x_scale ).floor() as i32;
let y1: i32 = ( (y2 as f64 + 0.5) * y_scale ).floor() as i32;