以编程方式确定图像的“均匀性”

以编程方式确定图像的“均匀性”

我正在尝试编写一个脚本来缩略图我们的数千个资产。这些资源大部分使用 Flash,我通过命令行上的 chromium 浏览器捕获它们。我现在非常需要站在它旁边才能让它发挥作用,这是一个 PITA。有帮助的是让我的脚本知道它何时制作了失败的缩略图,这种情况似乎经常发生。

“失败”往往是统一的颜色,要么是深灰色,要么是白色,我想我也许可以使用这种“统一程度”作为以编程方式评估缩略图成功与否的方法。以下是一些示例:

https://dl.dropboxusercontent.com/u/846812/permanent/thumb_examples/fail_1.jpg https://dl.dropboxusercontent.com/u/846812/permanent/thumb_examples/fail_2.jpg https://dl.dropboxusercontent.com/u/846812/permanent/thumb_examples/success1.jpg https://dl.dropboxusercontent.com/u/846812/permanent/thumb_examples/success2.jpg

让这个(我认为)更困难的是深灰色不是一种统一的颜色,而是一种重复的像素图案,近距离看起来像这样:

在此输入图像描述

所以它是统一的,但它是统一的重复模式。

任何人都可以想出一种方法可以在命令行中执行此操作吗?

答案1

我不知道你如何以编程方式做到这一点,这不是 100% 准确的事情,但是,由于你正在做一些接近屏幕抓取的事情,我建议你实际在屏幕上启动图像并使用xdtool,你可以采样许多随机样本图像上的点并检测像素颜色。如果全部或超过 95% 的颜色都相同,则可以肯定地说该图像是单色的。

另一种方法是存储常见的错误图像并将图像大小与错误图像的大小进行比较。我正在使用 VLC 从视频中提取静态图像作为我的视频库,在执行此操作时,我意识到,图像的对比度越高,我捕获的 png 文件的大小就越大。因此,请检查图像尺寸是否太小。毕竟,图像压缩就是最大限度地减少重复模式的存储量。您可以利用这一事实来发挥自己的优势。

答案2

你可以尝试一个方法尼尔·克拉维茨照片取证名声,确实:

  1. 减小尺寸。 Krawetz 将图像“粉碎”成 8x8 的正方形。
  2. 将 8x8 图像的颜色减少为灰度。
  3. 计算所得 64 种颜色的平均值。
  4. 计算 64 位数字 (8 * 8 = 64) - “每个位只是根据颜色值高于还是低于平均值来设置。
  5. 构造一个哈希。看起来 Krawetz 只是使用 64 位作为哈希值。

这类事情会让你的灰度图像和黑白图像变成非常不同的哈希值。您可能必须为此编写或找到一些非 shell 脚本代码。

我想到的另一个是寻找主色在图像中。那个人使用 Imagemagick 和awk,但我不确定你如何测试你的情况是否相等或相似。

更新

我刚刚发现解谜一次偶然的机会,“一个可以找到相似图片的图书馆”。只需要一点点编码就可以用它来做你想做的事情。

还有pH值,一个开源感知哈希库。这可能需要相同数量的编码。

这些都不完全满足您的要求,因为 libpuzzle 有 PHP 接口,而 pHash 似乎需要您编写 C 程序。

答案3

您可以使用 imagemagick 计算 FFT 并将其与已知的不良图像进行比较:

http://www.fmwconcepts.com/imagemagick/fourier_transforms/fourier.html#im_fft

答案4

写我自己的答案,因为我弄清楚了。好吧,无论如何,它似乎适用于我的测试图像。评论里已经解释了。

#!/bin/sh

#Tests whether an image is uniform (ie a simple repeated pattern or a single colour.)  

#The logic is as follows:
# - convert the image to an 8x8 px temp BMP image.  
#(we need to use bitmaps because we need exact pixel values 
#with no random compression artifacts)
# - convert THAT to a 1x1 px BMP image
# - convert the 1 px image back to an 8x8 px BMP image.

#If the first 8x8 image is the same (according to `diff`)   
#as the scaled-to-1px-and-back-again image, 
#then we can conclude that the first 8x8 image was totally uniform,
#(ie every pixel exactly the same) 
#and from this we can conclude that the original full size image 
#was also uniform:  not necessarily the same colour in every pixel,  
#but not varied enough for our requirements.

source=$1
small1=/tmp/small_image.bmp
small2=/tmp/small_image2.bmp
tiny=/tmp/tiny_image.bmp

#the \! after 8x8 tells it to ignore the aspect ratio and just squash it to those dimensions
convert "$source" -resize 8x8\! "$small1"
convert "$small1" -resize 1x1 "$tiny"
convert "$tiny" -resize 8x8 "$small2"
diff "$small1" "$small2" > /dev/null
result=$?
if [ $result -eq 0 ]; then
  #diff gives an empty return, so the files are the same, which means there wasn't variation
  echo "Image is uniform" >&1
else
  #we found a difference between the pre-squashed and resized versions which means there WAS variation
  echo "Image is not uniform" >&1
fi

相关内容