Java 实现SAD(绝对差之和)算法

Java 实现SAD(绝对差之和)算法,java,image-processing,Java,Image Processing,我正在实现一个JAVA程序来发现不同图像帧之间的相似性。 目前我正在使用两种不同的算法来实现这一点。 基本上,我将图像分成n*n个像素块,计算并比较。 现在我的主要问题是得到一个对某个像素有意义的值,目前我用两种不同的方法得到像素值: rgb值为0-255 //average pixel value double pixelValue = (getRed() + getGreen() + getBlue()) / 3.0; 或者 //sum of RGB as a data for pi

我正在实现一个JAVA程序来发现不同图像帧之间的相似性。 目前我正在使用两种不同的算法来实现这一点。 基本上,我将图像分成n*n个像素块,计算并比较。 现在我的主要问题是得到一个对某个像素有意义的值,目前我用两种不同的方法得到像素值:

rgb值为0-255

 //average pixel value
 double pixelValue = (getRed() + getGreen() + getBlue()) / 3.0;
或者

 //sum of RGB as a data for pixel value
 double pixelValue = (getRed() + getGreen() + getBlue());
问题在于,这两种情况下,这些值对像素来说都不是真正有意义的,因为完全蓝色或完全红色的像素会给出相同的值,因此,如果我的n*n块非常小,它可能会错误匹配。这对渐变图像或类似图像造成了重大问题。 将像素值获取为整数或浮点数的好方法或函数是什么,它们是像素的良好指示器?
数学函数也很好(甚至更好)。

彩色图像使用三维空间对每个空间位置的信息进行编码。 (通常)不可能找到唯一“标识”某个像素的单个唯一值

然而,有不同的数学技术可用于获得单个通道中的最大可变性

最简单的方法是从R、G和B通道的串联中生成一个24位数字。但是,这会导致问题,即差分函数对三个通道中每个通道的变化的响应会非常不同,这取决于它们的连接顺序

您已经探讨了三个通道相加的可能性,并指出这有一些明显的缺点

现在,对于数学上更严格的选项:

RGB颜色可以看作是三维空间中的一个向量,其中每个维度都是一个颜色通道。可以使用一种称为(PCA)的数学工具来找到一组新的正交基向量,从而可以将3D空间投影到其中。这些新向量具有这样的特性:每个连续向量使沿该向量的方差最大化。然后,第一个向量的值可以用作每个像素的最佳估计器。但是,PCA向量必须根据一组数据计算,这意味着每个图像的PCA向量不同。此外,PCA计算可能非常昂贵

有一种廉价的替代品也可以使用。对于自然图像,第一个PCA通常非常符合人类对亮度的感知(并非巧合,我们的人类视觉系统进化得非常高效)。对于使用sRGB原色存储的RGB图像(几乎所有消费RGB图像),存在一个简单的线性变换进行计算,这是亮度的良好近似值

最常用的功能是:

Y' = 0.2126 R' + 0.7152 G' + 0.0722 B'
此函数将给出单个通道中最大方差的良好近似值


所以,除非你真的需要最佳可能解(PCA),否则上面的Luma方程会给出一个很好的近似值。但是,由于您正在降低数据的维度,因此(几乎)永远不会得到完美的结果。

虽然我已经实现了Luma calc并正在尝试,我真的对PCA很感兴趣,肯定会读更多的书并尝试实现它。不仅是为了获得像素值,而且因为与SAD配对可以帮助我更有效地配对匹配块。也许可以。选择一个好的数据集来计算主成分是很重要的;一幅图像的主成分可能与下一幅图像的主成分不同,比较不同PCA之间的值在数学上没有意义。只需确保您要比较的所有数据都投影到相同的PCA空间。此外,如果您认为我满意地回答了您的问题,请不要忘记您可以接受我的答案。是的,当然,我只是在测试。我尝试过使用与本文所述类似的算法,不仅搜索帧之间的对应块,还搜索它们周围的像素。不幸的是,每帧大约需要1分钟,这是缓慢的,结果与我的实际实现类似,相反,可以准实时运行4x4块(示例是4x4块)是的,PCA算法不快;它归结为找到具有最大特征值的
n
特征向量,这归结为一个非常大的伪逆、一个逆和几个矩阵乘法。