形状检测

时间:2020-01-22 12:26:47

标签: python opencv image-processing

我尝试了3种算法:

  1. 通过Compare_ssim比较。
  2. 通过PIL进行差异检测(ImageChops.difference)。
  3. 图像减法。

第一个算法:

(score, diff) = compare_ssim(img1, img2, full=True)
diff = (diff * 255).astype("uint8")

第二种算法:

from PIL import Image ,ImageChops
img1=Image.open("canny1.jpg")
img2=Image.open("canny2.jpg")
diff=ImageChops.difference(img1,img2)
if diff.getbbox():
    diff.show()

第三种算法:

image3= cv2.subtract(image1,image2)

问题在于这些算法是如此敏感。如果图像具有不同的噪点,则他们认为这两个图像完全不同。有任何解决办法吗?

3 个答案:

答案 0 :(得分:3)

这些图片在很多方面都存在差异(变形,照明,颜色,形状),简单的图像处理无法处理所有这些问题。

我建议使用一种更高级的方法,该方法尝试以简单的几何图的形式提取那些管的几何形状和颜色。然后比较图形而不是图像。

enter image description here

我承认这说起来容易做起来难,并且只适用于这种特殊场景。

答案 1 :(得分:1)

很难提供帮助,因为我们真的不知道可以更改哪些参数,例如可以固定相机吗?总是会只管吗?灯管的颜色呢?

尽管如此,我认为您正在寻找的是图像注册框架,我建议您使用SimpleElastix。它主要用于医学图像,因此您可能必须熟悉SimpleITK库。有趣的是,您有很多参数可以控制注册。我认为您将不得不查看文档,以了解如何控制特定的图像频率,该频率会产生波动并使图像变形。此后,我没有将其配置为具有足够的局部失真,您必须找到最佳的权衡,但我认为它应该足够灵活。

无论如何,您可以通过以下代码获得这样的结果,我不知道这是否有帮助,希望如此:

import cv2
import numpy as np
import matplotlib.pyplot as plt
import SimpleITK as sitk

fixedImage = sitk.ReadImage('1.jpg', sitk.sitkFloat32)
movingImage = sitk.ReadImage('2.jpg', sitk.sitkFloat32)

elastixImageFilter = sitk.ElastixImageFilter()

affine_registration_parameters = sitk.GetDefaultParameterMap('affine')
affine_registration_parameters["NumberOfResolutions"] = ['6']
affine_registration_parameters["WriteResultImage"] = ['false']
affine_registration_parameters["MaximumNumberOfSamplingAttempts"] = ['4']

parameterMapVector = sitk.VectorOfParameterMap()
parameterMapVector.append(affine_registration_parameters)
parameterMapVector.append(sitk.GetDefaultParameterMap("bspline"))

elastixImageFilter.SetFixedImage(fixedImage)
elastixImageFilter.SetMovingImage(movingImage)
elastixImageFilter.SetParameterMap(parameterMapVector)
elastixImageFilter.Execute()

registeredImage = elastixImageFilter.GetResultImage()
transformParameterMap = elastixImageFilter.GetTransformParameterMap()

resultImage = sitk.Subtract(registeredImage, fixedImage)
resultImageNp = np.sqrt(sitk.GetArrayFromImage(resultImage) ** 2)

cv2.imwrite('gray_1.png', sitk.GetArrayFromImage(fixedImage))
cv2.imwrite('gray_2.png', sitk.GetArrayFromImage(movingImage))
cv2.imwrite('gray_2r.png', sitk.GetArrayFromImage(registeredImage))
cv2.imwrite('gray_diff.png', resultImageNp)

您的第一张图像调整为256x256:
first image
您的第二张图片:
second image
您的第二张图片已在第一张图片中注册:
second image registered
这是第一张图片和第二张图片之间的差异,可以显示出不同之处:
difference

答案 2 :(得分:0)

这是图像处理的经典问题之一,并且没有普遍适用的答案。可能的答案很大程度上取决于您拥有的图像类型,要从图像中提取的信息类型以及它们之间的差异。

您可以通过两种方式降低噪声: a)拍摄同一物体的几张图像,以使物体不变。您可以堆叠图像,并且以图像数量的平方根减少噪点。 b)您可以对图像运行模糊滤镜。模糊越多,平均噪点就越多。此处的噪声将减少平均像素数的平方根。但是图像中的细节也是如此。

在(a)和(b)两种情况下,您都应用了这两种方法后都要进行差异分析。

可能不适用于您,因为您可能无法抓住其中任何一个:如果您能获得平坦的视野,这会带来照度的不均匀性和相机的像素灵敏度,并允许在进行任何处理之前校正图像,则它会有所帮助。暗场的情况与此类似,它可以估计摄像机读出的噪声的影响,并可以校正这些噪声。

还有另一个第三种选择,它更高级:首先在足够详细的级别上运行对象分析。并比较结果。