【问题标题】:Algorithm to determine "visual clarity", or pixelation of an image确定“视觉清晰度”或图像像素化的算法
【发布时间】:2013-05-26 11:45:16
【问题描述】:

有没有这样的方法来确定图像可以放大多少直到它被认为是“失焦”?

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

我有一张以多种不同尺寸保存的图像,例如 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...上述问题只是此类算法如何有用的一个实际示例。

【问题讨论】:

  • 总是缩小。与缩小较大的原件相比,放大总是会产生较低质量的结果。最好删除不需要的数据,而不是尝试生成一开始就没有的数据。
  • @MarcB 实际上是非常正确的。始终缩小将确保您获得最佳图像质量,并且增加的尺寸充其量应该可以忽略不计(考虑到您不愿意放大小得多的图像,这会显着减小尺寸)。
  • 好吧,也许是这样...但是,一个不切实际的例子是:您宁愿将 250x250 的图像缩小到 121x121,还是将 120x120 增大...这种情况下的图像质量应该是绝对可以忽略不计,但服务器负载会低得多...
  • 确定使用算法的服务器负载比使用您描述的算法首先缩小要高得多。另外,您正在缓存您的渲染图像(?),所以它不应该是一次性的。
  • 是的,是的,你的权利......但是,在上传图像时做繁重的工作并将我所谓的“像素化索引”保存为静态数字不会导致在图像请求(只是简单的 int 比较)......此外,即使图像被缓存,我仍在处理请求“奇数”尺寸的用户

标签: php image-processing imagemagick


【解决方案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));
}

【讨论】:

  • 谢谢,边缘检测看起来很有希望,我会在接下来的几天里做一些测试,看看我是否能得到一个工作模型
  • @fiveDust nope...意识到它只是超出了我大脑的处理能力(目前)...我知道有些服务可以对图像进行类似的令人印象深刻的处理,例如 instartlogic.com/technology/smartvision 不幸的是它不是开源的,但值得一试
  • @anson 感谢您回来。你有没有试过 Imagick 的识别...识别 -verbose 文件名.jpg | grep 质量?
【解决方案2】:

这并不完全符合您的要求,但我认为它实现了您想要的。编写一个算法来量化图像的像素化程度并非易事,而且它肯定是特定于图像格式的(例如,适用于 PNG 图像),我真的不认为有必要实现你想要的。

因此,为了这个示例,我们假设您的所有图像都是完全正方形的(修改它以考虑非正方形图像是相当简单的):

假设您有一个可以调整大小的源图像列表,以及一个“结果大小” - 例如 500 像素 x 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 等)。我只会从最接近所需尺寸的源图像缩放。

【讨论】:

  • 谢谢你,虽然这样做只是找到最接近请求大小的图像......我正在寻找的解决方案可以处理任何不切实际的情况......另外,你的底部我不同意的段落,它不是关于“最终大小”,而是关于服务器必须加载大图像和小图像以及将失去什么质量。
  • Ex) 在您的示例中,我可以有一个 500x500 的图像和一个 100x100 的图像。如果请求的尺寸是 280x280,则“最接近”的图像是较小的图像,但这肯定会变得质量很差
  • 对 - 你的问题真的没有意义。您是在尝试最小化文件大小,还是最大化视觉清晰度?除非您愿意牺牲很多视觉质量,否则前者没有意义。否则,节省的费用是微不足道的。如果你想要后者,那么你应该按照别人的建议去做,只是总是缩小
  • 我正在寻找一种可以确定像素化的算法......文件大小实际上与算法无关,我只是将这部分作为一个实际示例进行讨论,以说明这种算法如何有用
  • 那为什么要说“以及我要解决的问题”?如果这只是一些深奥的例子,而算法真的会用于其他事情,那么我的答案将完全不同。但是,如果这确实是您要解决的问题,那么我会推荐另一种方法(即始终缩小)。
【解决方案3】:

您可以使用此 "Duplicate Image Finder" 的算法来比较高质量图像的指纹与低质量双胞胎的指纹。你怎么看?

【讨论】:

    【解决方案4】:

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

    但在所有条件相同的情况下,您可以假设高分辨率图像会缩小到比低分辨率图像放大到更好的质量。

    因此,在我的脑海中,您可以将较大的图片缩小到目标尺寸,然后将其用作评估放大的较小图片质量的指标(理想)(第 9 行的像素 7 有何不同来自理想图像中的相同像素等)。这种比较可以由所有像素或图像内的样本点进行。然后可以对生成的“outness”进行平均并用作放大图片质量的指示。

    【讨论】:

      猜你喜欢
      • 2015-04-27
      • 2013-06-04
      • 2014-01-07
      • 2014-06-17
      • 2012-12-07
      • 2013-07-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多