我正在实施一个JAVA程序来查找不同图像帧之间的相似性。 目前,我使用两种不同的算法来实现这一目标。 基本上我将图像分成n * n个像素块并为它们计算SAD并进行比较。 现在我的主要问题是得到一个对某个像素有意义的值,目前我以两种不同的方式得到像素值:
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块非常小,则它可以错误地匹配。这带来了梯度的显着问题图像或类似的。 将像素值作为整数或浮点数作为像素的良好指标的好方法或函数是什么? 数学函数也很好(甚至更好)。
答案 0 :(得分:1)
彩色图像使用三维来编码每个空间位置的信息。 (通常)不可能找到唯一“标识”某个像素的唯一值。
但是,有不同的数学技术可用于在单个通道中获得最大的可变性。
最天真的方法是简单地从R,G和B通道的串联中生成24位数。然而,这会导致问题,差异函数对三个通道中每个通道的变化的响应会有很大不同,具体取决于它们的连接顺序。
你已经探讨了三种渠道总和的可能性,并指出这有一些明显的缺点。
现在,对于更多数学上严格的选项:
RGB颜色可以被认为是三维空间中的矢量,其中每个维度是颜色通道之一。可以使用称为Principal Component Analysis(PCA)的数学工具来找到可以将3D空间投影到的新的正交基矢量集。这些新向量具有以下属性:每个连续向量使沿该向量的方差最大化。然后可以将第一矢量的值用作每个像素的最佳估计器。但是,必须从一组数据计算PCA向量,这意味着每个图像的PCA向量是不同的。此外,PCA计算可能非常昂贵。
也可以使用廉价替代品。对于自然图像,第一个PCA通常非常符合人类对亮度的感知(没有巧合,我们的人类视觉系统已经非常有效地发展)。对于使用sRGB原色(几乎所有消费者RGB图像)存储的RGB图像,存在一个简单的线性变换来计算Luma,这是一个很好的亮度近似值。
最常用的功能是:
Y' = 0.2126 R' + 0.7152 G' + 0.0722 B'
此函数可以很好地逼近单个通道中的最大方差。
因此,除非你真的需要最好的解决方案(PCA),否则上面的Luma方程将给出一个很好的近似值。但是,因为您正在减少数据的维度,所以(几乎)永远不会得到完美的结果。