我正在寻找对解决问题的最佳方法的一些见解。 我正在比较两个单独的图像之间的差异,但是我遇到了平移运动较小的问题。
我有一个“福音”图像,它本身就是“黄金标准”: 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)
当我执行上述步骤时,您会看到“福音”和所拍摄图像之间的某些翻译差异。最好的解决方法是什么,因为我只想获得字母黑色的差异,而不是对齐的程度?
答案 0 :(得分:0)
这是我在Python / OpenCV中如何进行模板匹配和差异化。
参考:
示例:
user
填充示例:
显示最佳匹配位置的相关图像:
匹配结果:
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)
"""
裁剪示例以使其与参考对齐:
差异图像(白色是不同的):