繁体   English   中英

测量图像 c++、opencv 中的均匀性/同质性

[英]Measure of uniformity / homogeniy in an Image c++, opencv

我想使用一个度量,它可以很好地表示灰度图像中的同质性/均匀性。

这是非均匀图像的示例:

在此处输入图片说明

这是一个统一图像的例子:

在此处输入图片说明

关于什么是一个好的解决方案的任何想法?

编辑:图像没有固定比例,即图像的宽度和高度是变化的。 添加更多上下文。 我在一个项目中使用它从侧视图 pov 区分公共汽车和卡车。 所以我添加的两个图像是卡车和公共汽车两个轮子之间的区域。 我观察到的是,该地区对于公共汽车来说是统一的,而对于卡车来说则是不统一的。 为了更精确地定义区域,它的宽度等于两个轮子之间的距离,高度等于整个轮子的高度。 为什么我使用这个区域:因为我正在接收公共汽车和卡车的灰度图像。 没有必要让整个车辆都适合图像,即很可能车辆的顶部(即略高于窗户)对我来说可能不可用,这就是这种方法的原因。

此处附加的图像采用 RGB,而我为项目接收的图像采用灰度。 我没有必要收到整车的图像。 下面的图片对我来说是最好的场景。

在此处输入图片说明 在此处输入图片说明

然而,这些区域不是恒定的,取决于公共汽车和卡车的大小。 所以我想用一个指标来衡量这些地区的均匀性。

一种测试图像局部同质性的方法(有点幼稚)是反复模糊图像并将最近的模糊与其之前的模糊之间的(绝对或平方)差异相加。 例如,对于您的前两个图像,重复模糊将很少改变类似渐变的图像,而对于第一个图像,每次连续的变化都会大得多。 考虑这个 Python 程序:

import cv2
import numpy as np

non = cv2.imread('img1.jpg', 0).astype(np.float32)/255
uni = cv2.imread('img2.jpg', 0).astype(np.float32)/255

blur_non = cv2.GaussianBlur(non, (11, 11), 2)
blur_uni = cv2.GaussianBlur(uni, (11, 11), 2)

for i in range(10):
    blur_non = cv2.GaussianBlur(blur_non, (11, 11), 2)
    blur_uni = cv2.GaussianBlur(blur_uni, (11, 11), 2)

last_blur_non = cv2.GaussianBlur(blur_non, (11, 11), 2)
last_blur_uni = cv2.GaussianBlur(blur_uni, (11, 11), 2)

ssd_blur_non = np.sum((last_blur_non - blur_non)**2)
ssd_blur_uni = np.sum((last_blur_uni - blur_uni)**2)

print('SSD Non-uniform: %f' % ssd_blur_non)
print('SSD Uniform:     %f' % ssd_blur_uni)

SSD 非均匀性:0.010601
SSD 统一:0.000321

所以我们在这里可以看到,均匀图像的最后两个模糊之间的平方差之和比非均匀图像小 33 倍。


可以通过设置阈值并查看在差异低于阈值之前需要多少模糊来制定另一个指标:

thresh = 1e-3

blur_count_non = 0
prev_blur_non = cv2.GaussianBlur(non, (11, 11), 2)
blur_non = cv2.GaussianBlur(blur_non, (11, 11), 2)
ssd_blur_non = np.sum((blur_non - prev_blur_non)**2)
while(ssd_blur_non > thresh):
    blur_non = cv2.GaussianBlur(prev_blur_non, (11, 11), 2)
    ssd_blur_non = np.sum((blur_non - prev_blur_non)**2)
    prev_blur_non = blur_non
    blur_count_non += 1

blur_count_uni = 0
prev_blur_uni = cv2.GaussianBlur(uni, (11, 11), 2)
blur_uni = cv2.GaussianBlur(blur_uni, (11, 11), 2)
ssd_blur_uni = np.sum((blur_uni - prev_blur_uni)**2)
while(ssd_blur_uni > thresh):
    blur_uni = cv2.GaussianBlur(prev_blur_uni, (11, 11), 2)
    ssd_blur_uni = np.sum((blur_uni - prev_blur_uni)**2)
    prev_blur_uni = blur_uni
    blur_count_uni += 1

print('Non-uniform blur count: %d' % blur_count_non)
print('Uniform blur count:     %d' % blur_count_uni)

非均匀模糊计数:79
均匀模糊计数:5

您可以读取这些值,例如“直到均匀的模糊数”。 如果您将阈值设置得更小,比如 0.01,那么实际上一次while循环(即两次模糊)会得到您所说的在阈值下大部分是同质的图像。 在本例中,两者之间的比率约为 16。


如果您为上述方法中的每个连续模糊绘制 SSD,您将看到如下内容:

连续模糊

很明显,这些线之一位于另一条之上。 当然,不太均匀的图像在每个模糊之间具有更高的总和差异,它应该或多或少地保持在顶部,尤其是在开始时。 第一种方法类似于在一定数量的迭代中绘制一条垂直线,并在该位置取最小值将对应于更均匀的图像。 第二种方法类似于画一条水平线并说“无论哪条线先碰到这条线,那条线都是同类的”。 不同的方向,相似的想法。 沿着同一路线的另一个想法:您可以检查 SSD变化之间的差异。 这就像“当两个点之间的斜率大部分变为水平时,图像是同质的”一样简单。 这当然发生在迭代次数的早期。


另一种流行的模糊方法是取两种不同模糊的差异; 也就是Kamil 提到的高斯差。 这种方法有时用于寻找图像中的边缘; 如果两个模糊之间存在很大差异,那是因为在图像中的某个点(例如边缘)对模糊的响应有所不同。 但是,如果它们或多或少类似地模糊,则图像非常平滑。

blur1_non = cv2.GaussianBlur(non, (7, 7), 1)
blur2_non = cv2.GaussianBlur(non, (31, 31), 2)
ssd_blur_non = np.sum((blur1_non - blur2_non)**2)

blur1_uni = cv2.GaussianBlur(uni, (7, 7), 1)
blur2_uni = cv2.GaussianBlur(uni, (31, 31), 2)
ssd_blur_uni = np.sum((blur1_uni - blur2_uni)**2)

print('SSD Non-uniform DoG: %f' % ssd_blur_non)
print('SSD Uniform DoG:     %f' % ssd_blur_uni)

SSD 非均匀狗:0.416841
SSD 制服狗:0.026028

这里的比率约为 20。


因此,所有这些方法都会在它们之间产生至少一个数量级的差异,这应该很容易检测到。 但是困难在于选择什么参数,高斯的标准偏差应该是多少,窗口的大小等。您可以尝试将它们基于大小,例如采用高斯窗口作为图像的一小部分尺寸。

注意:在这里我没有费心缩放图像大小; 您应该将所有总和除以图像中的像素数(即取平均值)以使其具有比例不变性。

我建议计算 2D FFT(快速傅立叶变换)。

https://en.wikipedia.org/wiki/Fast_Fourier_transform

它会将我们的图像强度域更改为频域。 如果您计算转换结果的幅度,它将产生这样的图像(下面的图像和结果示例): FFT结果 .

下面我附上了两张图片——左边不太统一,右边比较统一。 您可以在下面看到频域的差异:

在此处输入图片说明

您可以使用位于图像中心附近的信号(作为图像大小的百分比)计算信噪比。 该比率可以轻松用作指标。 FFT 方法在这里得到了很好的描述: https : //books.google.pl/books?id=97QebyNxyaYC&pg=PA51&lpg=PA51&dq=2dFFT+extract+mean+value&source=bl&ots=wV8kc-TrI-&sig=N35TiT3aI5HCYjopMxPmxKeBhVcWhCYpMXPmxKeBhVcVhCYpMXP6KsaVkXWhCYpMxPmxKeBhCypxPmxPhCypxPmxe #v=onepage&q=2dFFT%20extract%20mean%20value&f=false

另一种特征提取: http : //cns-classes.bu.edu/cn550/Lectures/Lecture13.pdf

类似的结果可以通过计算大窗口的DoG图像(高斯差),然后使用平均图像值作为度量(值越小图像越均匀)来实现。

关于什么:

  • 计算所有像素的平均值
  • 然后将实际像素值与计算平均值的差异相加

?

图像中的多样性越多,计算值就越高——这应该给出图像的同质性/均匀性的粗略估计。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM