用于确定“视觉清晰度”或图像像素化的算法

时间:2013-05-30 19:06:18

标签: php image-processing imagemagick

是否有任何这样的方法可以确定图像在被视为“失焦”之前可以放大多少?

一个实际的例子(以及我试图解决的问题):

我保存了几种不同尺寸的图像,比如500x500,250x250和120x120。我想提供最有效的形象,也是最清晰的。如果用户要以125x125请求图像,显然增加120x120图像以适应不仅效率最高,而且很可能不会导致任何明显的像素化。

然而,如果用户要以180x180请求图像,则增加120x120图像可能更有效,但很可能会渲染模糊图像。在这种情况下,我想缩小250x250图像。

显然,图像的“清晰度”可以是相对的,并且在不同的图像之间以及图像与图像之间有所不同,但我想知道是否存在任何类型的算法或函数来确定“像素化指数”各种...谢谢!

注意:使用PHP& ImageMagick用于图像处理,因此该领域的任何答案都会很棒......

澄清:我不是在寻找上面示例中的解决方案。我正在寻找原始问题的答案:is there an algorithm that could possibly determine how "pixelated" a blown up image is ......上述问题只是这种算法如何有用的一个实际例子。

4 个答案:

答案 0 :(得分:1)

您可以在图像上执行灰度级sobel边缘检测滤波器,并总结边缘的像素值;然后将此总和与像素数(SumOfEdges /(width * height))进行平均。这会告诉你图像的“边缘”。这只能用于比较图像类型。

这是我的sobel opencl过滤器内核

const sampler_t sampler = CLK_ADDRESS_CLAMP_TO_EDGE |
CLK_FILTER_NEAREST;
kernel void
sobel_grayscale(read_only image2d_t src, write_only image2d_t dst)
{
int x = get_global_id(0);
int y = get_global_id(1);

float4 p00 = read_imagef(src, sampler, (int2)(x - 1, y - 1));
float4 p10 = read_imagef(src, sampler, (int2)(x, y - 1));
float4 p20 = read_imagef(src, sampler, (int2)(x + 1, y - 1));
float4 p01 = read_imagef(src, sampler, (int2)(x - 1, y));
float4 p21 = read_imagef(src, sampler, (int2)(x + 1, y));
float4 p02 = read_imagef(src, sampler, (int2)(x - 1, y + 1));
float4 p12 = read_imagef(src, sampler, (int2)(x, y + 1));
float4 p22 = read_imagef(src, sampler, (int2)(x + 1, y + 1));

float4 gx = -p00 + p20 + 2.0f * (p21 - p01)-p02 + p22;

float4 gy = -p00 - p20 +2.0f * (p12 - p10) +p02 + p22;

float gs_x = 0.3333f * (gx.x + gx.y + gx.z);
float gs_y = 0.3333f * (gy.x + gy.y + gy.z);
float g = native_sqrt(gs_x * gs_x + gs_y * gs_y);
write_imagef(dst, (int2)(x, y), (float4)(g,g,g, 1.0f));
}

答案 1 :(得分:0)

这并不完全符合您的要求,但我认为它可以达到您想要的效果。编写一个算法来量化图像的像素化程度将是非常重要的,它肯定是图像格式特定的(例如,适用于PNG图像),我真的不认为有必要实现你想要的。

因此,为了这个例子,让我们假设你的所有图像都是完全正方形的(修改它以考虑非方形图像是相当微不足道的):

假设您有一个可以调整大小的源图像列表,以及“结果大小” - 比如500像素乘500像素。你可能会这样做:

$resultSize = 500;
$bestRatio = PHP_INT_MAX;
$bestURL = "";

foreach($sourceImageURLs as $url)
{
    $size = getimagesize($url);
    $size = $size[0];

    $ratio = min($resultSize, $size) / max($resultSize, $size);

    if($ratio < $bestRatio)
    {
        $bestRatio = $ratio;
        $bestURL = $url;
    }
}

/*
 * We've now found the image closest to our desired size. All we need
 * to do is resize the image at the URL in $bestURL to $resultSize, and
 * we're done.
 */

我认为我不会担心“效率最高”的图像 - 将100x100图像缩放到200x200而不是将300x300图像缩放到200x200会给你两张图像非常大小相似(特别是如果你使用一些好的压缩工具,比如PNGOUT等)。我只想从最接近所需大小的源图像缩放。

答案 2 :(得分:0)

您可以使用此Duplicate Image Finder的算法来比较优质图像的指纹与其低质量双胞胎的指纹。你觉得怎么样?

答案 3 :(得分:0)

图像质量完全是主观的,主要取决于原始图像的复杂程度。如果您的图像是暴风雪中的白色猫(基本上只是白色),那么500x500图像的主观质量将是相同的,无论您是通过减少1000x1000图像还是通过增加100x100图像来实现它。

但是在所有条件相同的情况下,你可以假设较高分辨率的图像会降低到比较低分辨率会扩大到更好的质量。

因此,我可以将较大的图片缩小到目标尺寸,然后将其用作评估放大的较小图片质量的指标(理想情况)(第9行的像素7有何不同)来自理想图像中的相同像素等)。可以对所有像素或图像内的采样点进行比较。然后可以对得到的“外观”进行平均,并将其用作放大图像质量的指示。