在Image c ++,opencv

时间:2017-09-27 09:30:14

标签: c++ opencv image-processing opencv3.0

我想使用一个衡量标准来衡量灰度图像中的均匀性/均匀性。

这是非均匀图像的示例:

enter image description here

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

enter image description here

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

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

这里附加的图像是RGB格式,而我收到的项目图像是灰度图像。我没有必要收到整车的图像。以下图片对我来说是最好的方案。

enter image description here enter image description here

然而,这些地区不是恒定的,取决于公共汽车和卡车的大小。因此,我想使用指标来衡量这些区域的一致性。

3 个答案:

答案 0 :(得分:6)

测试图像中局部均匀性的一种方法(稍微天真)将重复模糊图像并将最近模糊与之前模糊之间的(绝对或方形)差异相加。例如,对于前两个图像,重复模糊将非常少地改变类似梯度的图像,而对于第一个图像的第一个图像,每次连续的变化将大得多。考虑一下这个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,您将看到如下内容:

Successive blurs

这里很清楚,其中一条线位于另一条线之上。当然,不均匀的图像在每个模糊之间具有更高的总差异,并且它应该或多或少地保持在顶部,尤其是在开始时。第一种方法类似于在一定次数的迭代中绘制垂直线,并且在该位置处取得最小值将对应于更均匀的图像。第二种方法类似于绘制一条水平线并说“无论哪一条线首先击中均匀线条”。不同的方向,类似的想法。然而,另一个想法沿着同一条线:您可以检查SSD中更改之间的区别。这很简单,“只要斜率在两点之间变得大致水平,图像就是均匀的。”当然,迭代次数很早就会发生。

模糊的另一种流行方法是采用两种不同模糊的差异;又称高斯的差异为Kamil mentioned。有时使用此方法来查找图像中的边缘;如果两个模糊之间存在很大差异,那是因为在图像的某个点上对模糊有一些不同的反应,比如边缘。但如果它们或多或少地模糊,那么图像就非常流畅。

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非均匀DoG:0.416841
  SSD Uniform DoG:0.026028

这里的比例是20左右。

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

注意:这里我没有费心缩放图像尺寸;你应该将所有的和除以图像中的像素数(即取平均值),使其成为比例不变的。

答案 1 :(得分:3)

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

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

它会将我们的图像强度域更改为频域。如果计算转换结果的大小,它将生成这样的图像(在图像和结果示例下方): FFT results

下面我附上了两张图片 - 左侧不均匀,右侧更均匀。您可以在下面看到频域的差异:

enter image description here

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

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

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

答案 2 :(得分:0)

怎么样:

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

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