将重叠的图像彼此移开以获得准确的差异

时间:2019-05-14 07:27:34

标签: python opencv image-processing imagemagick image-comparison

我想获取使用相机捕获的打印件的图像差异。

我尝试了许多使用python库的解决方案:opencv,image-magic等。

我发现用于图像比较的解决方案是为了提高准确性:

  1. 移动图像:从左到右,并寻找最小的差异。
  2. 移动图像:从右到左,并寻找最小的差异。
  3. 移动图像:从上到下,并寻找最小的差异。
  4. 移动图像:从下到上,并寻找最小的差异。

捕获图像的条件: 1. 相机将永远不会移动(安装在固定支架上)。 2. 将对象手动放置在白板上,因此将永远无法正确对齐对象。 (每次手动操作时角度都会略有变化)

使用相机针对以下代码捕获的图像样本:

图片样本1:白色圆点:

Image 1  as original image

图片样本2:作为原始图片

Image 2 with white dotes

图像样本3:黑点

enter image description here

带有白点打印的接受输出不可用,但只能标记差异(缺陷):

Accepted output

当前,我正在使用以下Image-magic命令来实现图像差异:

compare -highlight-color black -fuzz 5% -metric AE Image_1.png Image_2.png -compose src diff.png

代码:

import subprocess

# -fuzz 5% # ignore minor difference between two images

cmd = 'compare -highlight-color black -fuzz 5% -metric AE Input.png output.png -compose src diff.png '

subprocess.call(cmd, shell=True)

差异后的输出不正确,因为比较工作在逐像素的情况下进行,因此仅标记实际差异还不够聪明:

output

我提到的上述解决方案可以有效地获得所需的输出差异,但是没有库或image-magic命令可用于此类图像比较。

是否要执行此操作的任何python代码或Image-magic命令?

2 个答案:

答案 0 :(得分:4)

似乎您正在执行一些缺陷检测任务。我想到的第一个解决方案是图像配准技术。 首先,请尝试在相同的条件下(光线,相机角度和...)拍摄图像(所提供的图像之一大于2像素)。

然后,您应该注册两张图像,然后将其与另一张图像匹配,就像这样

enter image description here

然后在单应矩阵的帮助下包装它们,并生成对齐的图像,在这种情况下,结果是这样的:

enter image description here

然后取对齐图像与查询图像的差值并对其进行阈值处理,得出结果:

enter image description here

正如我说的,如果您尝试更精确地拍摄帧,则套准结果会更好,并导致更精确的性能。

每个部分的代码:(大部分取自here)。

import cv2
import numpy as np


MAX_FEATURES = 1000
GOOD_MATCH_PERCENT = 0.5


def alignImages(im1, im2):
    # Convert images to grayscale
    im1Gray = cv2.cvtColor(im1, cv2.COLOR_BGR2GRAY)
    im2Gray = cv2.cvtColor(im2, cv2.COLOR_BGR2GRAY)

    # Detect ORB features and compute descriptors.
    orb = cv2.ORB_create(MAX_FEATURES)
    keypoints1, descriptors1 = orb.detectAndCompute(im1Gray, None)
    keypoints2, descriptors2 = orb.detectAndCompute(im2Gray, None)

    # Match features.
    matcher = cv2.DescriptorMatcher_create(cv2.DESCRIPTOR_MATCHER_BRUTEFORCE_HAMMING)
    matches = matcher.match(descriptors1, descriptors2, None)

    # Sort matches by score
    matches.sort(key=lambda x: x.distance, reverse=False)

    # Remove not so good matches
    numGoodMatches = int(len(matches) * GOOD_MATCH_PERCENT)
    matches = matches[:numGoodMatches]

    # Draw top matches
    imMatches = cv2.drawMatches(im1, keypoints1, im2, keypoints2, matches, None)
    cv2.imwrite("matches.jpg", imMatches)

    # Extract location of good matches
    points1 = np.zeros((len(matches), 2), dtype=np.float32)
    points2 = np.zeros((len(matches), 2), dtype=np.float32)

    for i, match in enumerate(matches):
        points1[i, :] = keypoints1[match.queryIdx].pt
        points2[i, :] = keypoints2[match.trainIdx].pt

    # Find homography
    h, mask = cv2.findHomography(points1, points2, cv2.RANSAC)

    # Use homography
    height, width, channels = im2.shape
    im1Reg = cv2.warpPerspective(im1, h, (width, height))

    return im1Reg 
if __name__ == '__main__':

  # Read reference image
  refFilename = "vv9gFl.jpg" 
  imFilename =  "uP3CYl.jpg" 
  imReference = cv2.imread(refFilename, cv2.IMREAD_COLOR) 
  im = cv2.imread(imFilename, cv2.IMREAD_COLOR) 

  # Registered image will be resotred in imReg. 
  # The estimated homography will be stored in h. 
  imReg = alignImages(im, imReference)

  # Write aligned image to disk. 
  outFilename = "aligned.jpg" 
  cv2.imwrite(outFilename, imReg) 

图像差异和阈值:     倾斜= cv2.imread(“ aligned.jpg”,0)     alined = alined [:,:280]

b = cv2.imread("vv9gFl.jpg", 0 )
b = b[:, :280]

print (alined.shape)
print (b.shape)

diff = cv2.absdiff(alined, b)
cv2.imwrite("diff.png", diff)

threshold = 25
alined[np.where(diff >  threshold)] = 255
alined[np.where(diff <= threshold)] = 0

cv2.imwrite("threshold.png", diff) 

如果您有很多图像并且想要执行缺陷检测任务,建议您使用Denoising Autoencoder训练深度人工神经网络。了解更多here

答案 1 :(得分:2)

尽管您不希望进行逐点处理,但这是使用Imagemagick进行的子图像搜索比较。它会在裁掉黑色图像后填充一张图像,然后将其移到较小的位置,找到较大的最佳匹配位置。

裁剪图像1:

convert image1.jpg -gravity north -chop 0x25 image1c.png


enter image description here

裁剪并填充图像2:

convert image2.jpg -gravity north -chop 0x25 -gravity center -bordercolor "rgb(114,151,157)" -border 20x20 image2c.png


enter image description here

进行子图像搜索

compare -metric rmse -subimage-search image2c.png image1c.png null:
1243.41 (0.0189732) @ 22,20

现在移动并获取两个图像之间的差异

convert image2c.png image1c.png -geometry +22+20 -compose difference -composite -shave 22x20 -colorspace gray -auto-level +level-colors white,red diff.png


enter image description here

添加:

如果只想使用compare,则需要在compare命令中添加-fuzz 15%:

compare -metric rmse -fuzz 15% -subimage-search image2c.png image1c.png diff.png


产生两个图像。差异图片是第一个,所以请看diff-0.png

enter image description here