这是我想做的:

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

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

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


当前回答

如果现在回复太晚,我很抱歉,但因为我一直在做类似的事情,我想我可以在某种程度上做出贡献。

也许在OpenCV中你可以使用模板匹配。假设你用的是摄像头

简化图像(可能是阈值?) 应用模板匹配和检查max_val与minMaxLoc

提示:max_val(或min_val取决于所使用的方法)将为您提供数字,较大的数字。为了获得百分比上的差异,使用与相同图像匹配的模板—结果将是100%。

举例的伪代码:

previous_screenshot = ...
current_screenshot = ...

# simplify both images somehow

# get the 100% corresponding value
res = matchTemplate(previous_screenshot, previous_screenshot, TM_CCOEFF)
_, hundred_p_val, _, _ = minMaxLoc(res)

# hundred_p_val is now the 100%

res = matchTemplate(previous_screenshot, current_screenshot, TM_CCOEFF)
_, max_val, _, _ = minMaxLoc(res)

difference_percentage = max_val / hundred_p_val

# the tolerance is now up to you

希望能有所帮助。

其他回答

一个简单的解决方案:

将图像编码为jpeg格式,并寻找文件大小的实质性变化。

我曾经用视频缩略图实现过类似的东西,并且取得了很大的成功和可伸缩性。

下面是我写的一个函数,它以2个图像(文件路径)作为参数,并返回两个图像“像素”组件之间的平均差值。这对我确定视觉上“相等”的图像(当它们不==相等时)非常有效。

(我发现8个是判断图像本质上是否相同的一个很好的限制。)

(如果不添加预处理,图像必须具有相同的尺寸。)

from PIL import Image

def imagesDifference( imageA, imageB ):
    A = list(Image.open(imageA, r'r').convert(r'RGB').getdata())
    B = list(Image.open(imageB, r'r').convert(r'RGB').getdata())
    if (len(A) != len(B)): return -1
    diff = []
    for i in range(0, len(A)):
        diff += [abs(A[i][0] - B[i][0]), abs(A[i][1] - B[i][1]), abs(A[i][2] - B[i][2])]
    return (sum(diff) / len(diff))

你可以计算这两个图像的直方图,然后计算Bhattacharyya系数,这是一个非常快速的算法,我已经用它来检测板球视频中的镜头变化(在C中使用openCV)

一种更有原则的方法是使用全局描述符来比较图像,比如GIST或CENTRIST。这里描述的哈希函数也提供了类似的解决方案。

通过计算均方误差,numpy有一个简单而快速的解决方案:

before = np.array(get_picture())
while True:
    now = np.array(get_picture())
    MSE = np.mean((now - before)**2)

    if  MSE > threshold:
        break

    before = now