这是我想做的:

我定期用网络摄像头拍照。就像时间流逝一样。然而,如果没有什么真正的改变,也就是说,图片看起来几乎相同,我不想存储最新的快照。

我想有某种方法可以量化这种差异,我必须根据经验确定一个阈值。

我追求的是简单而不是完美。 我用的是python。


当前回答

I have been having a lot of luck with jpg images taken with the same camera on a tripod by (1) simplifying greatly (like going from 3000 pixels wide to 100 pixels wide or even fewer) (2) flattening each jpg array into a single vector (3) pairwise correlating sequential images with a simple correlate algorithm to get correlation coefficient (4) squaring correlation coefficient to get r-square (i.e fraction of variability in one image explained by variation in the next) (5) generally in my application if r-square < 0.9, I say the two images are different and something happened in between.

这是强大的和快速的在我的实现(Mathematica 7)

这是值得玩转的部分,你感兴趣的图像,并通过裁剪所有的图像到那个小区域,否则一个远离相机但重要的变化将被错过。

我不知道如何使用Python,但我确信它也有相关性,不是吗?

其他回答

我也遇到了同样的问题,写了一个简单的python模块,使用pillow的ImageChops来比较两个相同大小的图像,创建一个黑白差异图像,并总结直方图值。

你可以直接得到这个分数,也可以得到一个百分比值,与完整的黑白差异进行比较。

它还包含一个简单的is_equal函数,可以在图像传递为相等的情况下(并包括)提供一个模糊阈值。

这种方法不是很详细,但可能对其他正在与相同问题斗争的人有用。

https://pypi.python.org/pypi/imgcompare/

两种流行且相对简单的方法是:(a)已经提出的欧几里得距离,或(b)标准化互相关。与简单的互相关相比,归一化互相关对光照变化的影响明显更强。维基百科给出了一个标准化互相关的公式。更复杂的方法也存在,但它们需要更多的工作。

使用numpy-like语法,

dist_euclidean = sqrt(sum((i1 - i2)^2)) / i1.size

dist_manhattan = sum(abs(i1 - i2)) / i1.size

dist_ncc = sum( (i1 - mean(i1)) * (i2 - mean(i2)) ) / (
  (i1.size - 1) * stdev(i1) * stdev(i2) )

假设i1和i2为二维灰度图像阵列。

使用SSIM测量两幅图像之间的结构相似指数度量。

我在工作中遇到了类似的问题,我正在重写我们的图像转换端点,我想检查新版本是否与旧版本产生相同或几乎相同的输出。所以我写了这个:

https://github.com/nicolashahn/diffimg

它对相同大小的图像进行操作,并在每个像素级别上测量每个通道的值的差异:R, G, B(, a),取这些通道的平均差值,然后对所有像素的差值进行平均,并返回一个比率。

例如,有一张10x10的白色像素的图像,而同一张图像只有一个像素变成了红色,该像素处的差异是1/3或0.33……(RGB 0,0,0 vs 255,0,0)并且在所有其他像素为0。总共100像素,0.33…/100 =一个~0.33%的图像差异。

我相信这将非常适合OP的项目(我意识到这是一个非常老的帖子,但张贴为未来的StackOverflowers谁也想用python比较图像)。

另一个衡量两张图片相似度的好方法是:

import sys
from skimage.measure import compare_ssim
from skimage.transform import resize
from scipy.ndimage import imread

# get two images - resize both to 1024 x 1024
img_a = resize(imread(sys.argv[1]), (2**10, 2**10))
img_b = resize(imread(sys.argv[2]), (2**10, 2**10))

# score: {-1:1} measure of the structural similarity between the images
score, diff = compare_ssim(img_a, img_b, full=True)
print(score)

如果其他人对更强大的比较图像相似性的方法感兴趣,我将使用Tensorflow测量和可视化相似图像的教程和web应用程序放在一起。