python - 将重叠图像相互移动以获得准确的差异

标签 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 for print with white dots is not available, 但它应该只标记差异(缺陷):

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

我提到的上述解决方案将努力获得所需的差异作为输出,但没有可用于此类图像比较的库或图像魔术命令。

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

最佳答案

看来您正在执行一些缺陷检测任务。我想到的第一个解决方案是图像配准技术。 首先尝试在相同条件下(照明、相机角度和...)拍摄图像(您提供的图像之一大 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) 

对于图像差异和阈值处理: alined = 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 .

关于python - 将重叠图像相互移动以获得准确的差异,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56125062/

相关文章:

android - 为什么 OpenCV4Android 的 pointPolygonTest() 方法为每个像素返回-1?

python - 天文FITS图像校准: Indexing issue using ccdproc

iphone - 使用opencv提取blob

java - 使用java创建图像文件

python - 如何从 subprocess.Popen.stdout 读取所有可用数据(非阻塞)?

python - 列出python中的重复数据串联

python - 使用 Keras 递归神经网络进行预测 - 准确度始终为 1.0

python - 在 Django 中扩展用户配置文件。管理员创建用户

c++ - Unresolved external cv::flip cv::imshow

python - 如何提取照片的对比度 - opencv