python compare 打印差异_如何量化两幅图像之间的差异?

大概的概念

选项1:将两个图像加载为数组(scipy.misc.imread)并计算元素(逐个像素)的差异。计算差异的标准。

选项2:加载两个图像。计算每个特征向量的某些特征向量(如直方图)。计算特征向量而不是图像之间的距离。

但是,首先要做出一些决定。

问题

你应该先回答这些问题:图像的形状和尺寸是否相同?

如果没有,您可能需要调整大小或裁剪它们。PIL库将有助于在Python中完成它。

如果使用相同的设置和相同的设备,它们可能是相同的。

图像是否良好对齐?

如果没有,您可能希望首先运行互相关,以便首先找到最佳对齐。SciPy具有执行此功能的功能。

如果相机和场景仍然存在,则图像可能会很好地对齐。

曝光的图像总是一样吗?(亮度/对比度是否相同?)

如果没有,您可能想要标准化图像。

但是要小心,在某些情况下,这可能比错误做得更多。例如,暗背景上的单个亮像素将使标准化图像非常不同。

颜色信息重要吗?

如果要注意颜色变化,则每个点都会有一个颜色值矢量,而不是灰度图像中的标量值。编写此类代码时需要更多关注。

图像中是否有明显的边缘?他们可能会搬家吗?

如果是,您可以首先应用边缘检测算法(例如,使用Sobel或Prewitt变换计算梯度,应用一些阈值),然后将第一个图像上的边缘与第二个图像上的边缘进行比较。

图像中有噪音吗?

所有传感器都会以一定的噪音污染图像。低成本传感器具有更多噪音。您可能希望在比较图像之前应用一些降噪功能。模糊是这里最简单(但不是最好)的方法。

你想注意什么样的变化?

这可能会影响用于图像之间差异的规范选择。

考虑使用曼哈顿范数(绝对值的总和)或零范数(元素的数量不等于零)来测量图像的变化程度。前者将告诉您图像关闭了多少,后者只会告诉您有多少像素不同。

我假设你的图像是完全对齐的,相同的大小和形状,可能有不同的曝光。为简单起见,我将它们转换为灰度,即使它们是彩色(RGB)图像。

您将需要这些导入:import sysfrom scipy.misc import imreadfrom scipy.linalg import normfrom scipy import sum, average

主要功能,读取两个图像,转换为灰度,比较和打印结果:def main():

file1, file2 = sys.argv[1:1+2]

# read images as 2D arrays (convert to grayscale for simplicity)

img1 = to_grayscale(imread(file1).astype(float))

img2 = to_grayscale(imread(file2).astype(float))

# compare

n_m, n_0 = compare_images(img1, img2)

print "Manhattan norm:", n_m, "/ per pixel:", n_m/img1.size    print "Zero norm:", n_0, "/ per pixel:", n_0*1.0/img1.size

如何比较。img1并且img2是2D SciPy数组:def compare_images(img1, img2):

# normalize to compensate for exposure difference, this may be unnecessary

# consider disabling it

img1 = normalize(img1)

img2 = normalize(img2)

# calculate the difference and its norms

diff = img1 - img2  # elementwise for scipy arrays

m_norm = sum(abs(diff))  # Manhattan norm

z_norm = norm(diff.ravel(), 0)  # Zero norm

return (m_norm, z_norm)

如果文件是彩色图像,则imread返回3D阵列,平均RGB通道(最后一个阵列轴)以获得强度。无需为灰度图像(例如.pgm):def to_grayscale(arr):

"If arr is a color image (3D array), convert it to grayscale (2D array)."

if len(arr.shape) == 3:

return average(arr, -1)  # average over the last axis (color channels)

else:

return arr

归一化是微不足道的,您可以选择归一化为[0,1]而不是[0,255]。arr这里是一个SciPy数组,因此所有操作都是按元素进行的:def normalize(arr):

rng = arr.max()-arr.min()

amin = arr.min()

return (arr-amin)*255/rng

运行main功能:if __name__ == "__main__":

main()

现在,您可以将所有内容放在脚本中并针对两个图像运行。如果我们将图像与自身进行比较,则没有区别:$ python compare.py one.jpg one.jpgManhattan norm: 0.0 / per pixel: 0.0Zero norm: 0 / per pixel: 0.0

如果我们模糊图像并与原始图像进行比较,则存在一些差异:$ python compare.py one.jpg one-blurred.jpg

Manhattan norm: 92605183.67 / per pixel: 13.4210411116Zero norm: 6900000 / per pixel: 1.0

更新:相关技术

由于问题是关于视频序列,帧可能几乎相同,并且你寻找一些不寻常的东西,我想提一些可能相关的替代方法:背景减法和分割(检测前景对象)

稀疏光流(检测运动)

比较直方图或一些其他统计数据而不是图像

我强烈建议您查看“学习OpenCV”一书,第9章(图像部分和分割)和第10章(跟踪和动作)。前者教导使用背景减法方法,后者给出了光流方法的一些信息。所有方法都在OpenCV库中实现。如果您使用Python,我建议使用OpenCV≥2.3及其cv2Python模块。

最简单的背景减法版本:学习背景的每个像素的平均值μ和标准偏差σ

将当前像素值与(μ-2σ,μ+2σ)或(μ-σ,μ+σ)的范围进行比较

更高级的版本会考虑每个像素的时间序列并处理非静态场景(如移动树木或草地)。

光流的想法是采用两个或更多帧,并将速度矢量分配给每个像素(密集光流)或其中一些(稀疏光流)。要估计稀疏光流,您可以使用Lucas-Kanade方法(它也在OpenCV中实现)。显然,如果存在大量流量(速度场的最大值高于平均值),那么帧中的某些东西会移动,后续图像会更加不同。

比较直方图可以帮助检测连续帧之间的突然变化。这种方法在Courbon等人,2010年使用:连续帧的相似性。测量两个连续帧之间的距离。如果它太高,则意味着第二帧被破坏,因此图像被消除。所述的Kullback-Leibler距离,或互熵,对两帧的直方图:

其中p和q是帧的直方图。阈值固定为0.2。

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值