如何按“爆发”对图像进行分组?

时间:2015-06-17 01:15:50

标签: python image-processing

我认为这需要一些解释,所以请耐心等待......

我一次以4-6秒的亚秒级突发拍摄了2000多张图像。他们都被丢弃在同一个地方,所以我需要对它们进行排序。我需要通过突发对它们进行排序,但EXIF数据只提供一分钟的分辨率。爆发应该几乎完全相同,并且不同的爆发被设计为显着不同。

我需要查看每张图片,将其与下一张图片进行比较,看看它是否相似。如果它太不同了,它必须来自另一个爆发,它需要进入一个新的文件夹,以及下面的任何类似的图像,依此类推。

我的想法是将当前图像的每个像素与下一个像素之间的差值的绝对值相加。一旦该总和达到阈值,那么这必然意味着它们来自不同的爆发(我可以做一些测试以找出一个好的阈值)。

最大的问题是怎么样? PIL / Pillow支持这样的东西吗?有没有更好的方法来查看一个图像是否“大部分”与另一个图像相同?

我比使用任何特定技术更快地对它们进行排序,因此欢迎使用其他方法。

......它几乎必须是Python。

编辑: 这是一对样本图像,它们都应该放在同一个文件夹中: 001 002

这些是来自以下爆发的两个图像,应该放在另一个文件夹中: 003 004

4 个答案:

答案 0 :(得分:3)

如果您想要进行基于内容的匹配,而不是上述优秀人员建议的基于时间戳的排序,那么OpenCV库是一个不错的选择。查看这篇文章,了解如何将OpenCV库用于图像相似性匹配的不同技术:Checking images for similarity with OpenCV

关于同一主题有很多SO问题,所以阅读它们会给你一个更好的主意。

根据上面的时间观点,当我只绘制拍摄照片的时间时,这是我得到的情节:

Clusters

不同的颜色代表不同的文件夹(应该使用不同的颜色地图以获得更好的可见性,但是很好......)。

基于这些时间,它看起来像群集间时间,明显比群集内时间更明显。

我还在下面的输出中计算了一些群集内和群集间指标:

folder: ImageBurstsDataset/001
Total image files in folder: 6
Total intra-cluster time: 1.0
Average intra-cluster time: 0.166666666667
Max: 1.0, Min: 0.0

folder: ImageBurstsDataset/002
Total image files in folder: 7
Total intra-cluster time: 1.0
Average intra-cluster time: 0.142857142857
Max: 1.0, Min: 0.0

folder: ImageBurstsDataset/003
Total image files in folder: 6
Total intra-cluster time: 1.0
Average intra-cluster time: 0.166666666667
Max: 1.0, Min: 0.0

folder: ImageBurstsDataset/004
Total image files in folder: 6
Total intra-cluster time: 2.0
Average intra-cluster time: 0.333333333333
Max: 1.0, Min: 0.0

folder: ImageBurstsDataset/005
Total image files in folder: 6
Total intra-cluster time: 2.0
Average intra-cluster time: 0.333333333333
Max: 1.0, Min: 0.0

folder: ImageBurstsDataset/006
Total image files in folder: 6
Total intra-cluster time: 1.0
Average intra-cluster time: 0.166666666667
Max: 1.0, Min: 0.0

folder: ImageBurstsDataset/007
Total image files in folder: 6
Total intra-cluster time: 2.0
Average intra-cluster time: 0.333333333333
Max: 1.0, Min: 0.0

folder: ImageBurstsDataset/008
Total image files in folder: 5
Total intra-cluster time: 2.0
Average intra-cluster time: 0.4
Max: 1.0, Min: 0.0

folder: ImageBurstsDataset/009
Total image files in folder: 6
Total intra-cluster time: 1.0
Average intra-cluster time: 0.166666666667
Max: 1.0, Min: 0.0

folder: ImageBurstsDataset/010
Total image files in folder: 6
Total intra-cluster time: 2.0
Average intra-cluster time: 0.333333333333
Max: 1.0, Min: 0.0


Inter-cluster times: [10.0, 8.0, 7.0, 5.0, 6.0, 6.0, 5.0, 10.0, 6.0]

免责声明:匆忙编写此脚本,只需要返回并确保所有边缘情况都正确。但是否则......我从您上传的数据集中得出的结论是:

  1. 在群集中,一张图片与前一张图片相差不超过1秒。

  2. 下一个群集中的第一张图片距离上一个群集中的最后一张图片至少有5秒钟。

答案 1 :(得分:2)

对不起,原来EXIF数据就是这样。看起来爆发之间有10-15秒的好时间,所以当一个结束而另一个结束时,它应该很容易分辨。

PIL / Pillow有足够的工具可以使用以下方式查看创建日期:

from PIL.ExifTags import TAGS

def get_exif(fn):
    ret = {}
    i = Image.open(fn)
    info = i._getexif()
    for tag, value in info.items():
        decoded = TAGS.get(tag, tag)
        ret[decoded] = value
    return ret

......或类似的东西。

答案 2 :(得分:1)

两张图片的相似之处是一个开放的研究问题。但是,鉴于您的图像是快速拍摄的,使用绝对差异是合理的。另一种可能性是使用相关性,例如,乘以像素值并接受高于阈值的结果。

问题在于速度。根据您对准确性的要求,您可以非常显着地对图像进行二次采样。可能是比较100或1000个均匀分布的像素的值 - 每个图像中的相同像素 - 将为您提供足够准确的统计数据。

答案 3 :(得分:1)

PIL可以提供图像的RGB数据,理论上可以用于比较图像。要测量两个图像的接近程度,您可能需要计算两个图像的差异,甚至计算统计方法的误差。您可以使用

获取RGB数据
import Image
pic  = Image.open('/path/to/file')
rgbdata = pic.load()
width, height = pic.size

您可以完全根据rgbdata [i,j]中第ij个像素的RGB值查看数据。

希望这有帮助。

[编辑] 这种方法只能假设所有图片都在同一帧中拍摄...如果相机移动了一点,这将无法正常工作。

如果它们来自三脚架上的相机(静止)并且物体正在移动,那么我们甚至可以追踪物体的移动(像素值差异更大)。

否则,必须在面部识别类应用程序中定义跟踪器点。 (我不是图像处理方面的专家,但看到很少有应用程序以这种方式工作)

比较两个图像的另一种方法是傅立叶域。但不确定它对你有多好。