图像差异:忽略平移运动

时间:2020-03-23 21:06:34

标签: python image opencv

我正在寻找对解决问题的最佳方法的一些见解。 我正在比较两个单独的图像之间的差异,但是我遇到了平移运动较小的问题。

我有一个“福音”图像,它本身就是“黄金标准”: gospel image

然后我要比较多个不同的拍摄图像。 这是一个示例:example image

以下是显示我的问题的示例差异图片:difference image

如您所见,它们很小。我现在要区分图像的方式是,首先将图像调整为32x32,手动将对比度降低100,然后使用OpenCV施加模糊效果。

之后,我使用skimage的'structural_integrity'函数减去并量化图像之间的差异。其余的纯粹用于查看。

import cv2
import numpy as np
from PIL import Image
from skimage.metrics import structural_similarity

def change_contrast(img, level):
    img = Image.fromarray(img)
    factor = (259 * (level + 255)) / (255 * (259 - level))
    def contrast(c):
        return 128 + factor * (c - 128)
    return np.asarray(img.point(contrast))

# Open and preprocess the images
image_orig = cv2.imread(IMAGE_PATH)
image = cv2.resize(image, (32, 32))
image = change_contrast(image_orig, -100)
image = cv2.blur(image, (5, 5))
image = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)

gospel_orig = cv2.imread(GOSPEL_PATH)
gospel = cv2.resize(gospel_orig, (32, 32))
gospel = change_contrast(gospel, -100)
gospel = cv2.blur(gospel, (5, 5))
gospel = cv2.cvtColor(gospel, cv2.COLOR_BGR2GRAY)

# Get image similarities and an output difference image
(score, diff) = structural_similarity(image, gospel, full=True)
print("Image similarity", score)

diff = (diff * 255).astype("uint8")

# Viewing stuff below
thresh = cv2.threshold(diff, 0, 255, cv2.THRESH_BINARY_INV | cv2.THRESH_OTSU)[1]
contours = cv2.findContours(thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
contours = contours[0] if len(contours) == 2 else contours[1]

filled_gospel = cv2.cvtColor(gospel, cv2.COLOR_GRAY2BGR)

for c in contours:
    area = cv2.contourArea(c)
    if area > 40:
        x,y,w,h = cv2.boundingRect(c)
        cv2.drawContours(filled_gospel, [c], 0, (0,255,0), -1)

cv2.imshow('image', image)
cv2.imshow('gospel', gospel)
cv2.imshow('diff',diff)
cv2.imshow('filled gospel',filled_gospel)
cv2.waitKey(0)

当我执行上述步骤时,您会看到“福音”和所拍摄图像之间的某些翻译差异。最好的解决方法是什么,因为我只想获得字母黑色的差异,而不是对齐的程度?

1 个答案:

答案 0 :(得分:0)

这是我在Python / OpenCV中如何进行模板匹配和差异化。

  • 阅读参考图片和示例图片
  • 使用背景灰色将示例图像填充到其尺寸的两倍。
  • 使用参考进行模板匹配,以找到最佳匹配位置和匹配分数。
  • 裁剪的示例图像的左上角位于匹配位置,但参考图像的大小
  • 获取绝对差异图像
  • 保存结果

参考:

enter image description here

示例:

enter image description here

user


填充示例:

enter image description here

显示最佳匹配位置的相关图像:

enter image description here

匹配结果:

def f(s, low, high):
  if low == high:
    return not s[low].islower()

  mid = low + (high - low) // 2
  left = f(s, low, mid)
  right = f(s, mid + 1, high)

  return (left and right) or (not left and not right)

strs = [
  "Abc",
  "ABc",
  "asdf",
  "aSdF",
  "ASdf",
  "AsDF"
]

for s in strs:
  print(s, f(s, 0, len(s) - 1))

"""
('Abc', True)
('ABc', False)
('asdf', True)
('aSdF', True)
('ASdf', True)
('AsDF', False)
"""


裁剪示例以使其与参考对齐:

enter image description here

差异图像(白色是不同的):

enter image description here