【问题标题】:how to detect image translation with only numpy and PIL如何仅使用 numpy 和 PIL 检测图像翻译
【发布时间】:2020-01-30 03:09:57
【问题描述】:

给定两张图片,我需要检测两者之间是否存在平移偏移。我只能使用 numpy 和 PIL。

This post 展示了如何使用 PIL 应用 (x, y) 翻译,但还没有找到类似的东西来检测翻译。

根据我的阅读,互相关似乎是解决方案的一部分,并且有 numpy.correlate 函数。但是,我不知道如何使用这个函数的输出来检测水平和垂直平移坐标。

first image

second image

【问题讨论】:

  • 请提供两张图片。谢谢。
  • 我发布了一个答案,然后意识到您指定了“仅限 NumPy 和 PIL”......对此感到抱歉。我明天再看看。
  • 谢谢!不用担心。我知道那是更明智的方法,但不幸的是我的情况有限。你的回答让我对如何解释相关结果和找到偏移量的一般过程有了一些见解,我会读一遍!
  • 我用scipy-free 替代方案修改了我的答案。

标签: python numpy image-processing python-imaging-library


【解决方案1】:

由于这些(几乎)是二维数组,因此您需要 scipy.signal.correlate2d() 函数。

首先,读取您的图像并将其转换为数组:

import numpy as np
from PIL import Image
import requests
import io

image1 = "https://i.stack.imgur.com/lf2lc.png"
image2 = "https://i.stack.imgur.com/MMSdM.png"

img1 = np.asarray(Image.open(io.BytesIO(requests.get(image1).content)))
img2 = np.asarray(Image.open(io.BytesIO(requests.get(image2).content)))

# img2 is greyscale; make it 2D by taking mean of channel values.
img2 = np.mean(img2, axis=-1)

现在我们有了两张图片,我们可以修改the scipy.signal.correlate2d() documentation中的示例:

from scipy import signal

corr = signal.correlate2d(img1, img2, mode='same')

如果您出于某种原因想避免使用scipy,那么这应该是等效的:

pad = np.max(img1.shape) // 2
fft1 = np.fft.fft2(np.pad(img1, pad))
fft2 = np.fft.fft2(np.pad(img2, pad))
prod = fft1 * fft2.conj()
result_full = np.fft.fftshift(np.fft.ifft2(prod))
corr = result_full.real[1+pad:-pad+1, 1+pad:-pad+1]

现在我们可以计算最大相关的位置:

y, x = np.unravel_index(np.argmax(corr), corr.shape)

现在我们可以将结果可视化,再次调整文档示例:

import matplotlib.pyplot as plt

y2, x2 = np.array(img2.shape) // 2

fig, (ax_img1, ax_img2, ax_corr) = plt.subplots(1, 3, figsize=(15, 5))
im = ax_img1.imshow(img1, cmap='gray')
ax_img1.set_title('img1')
ax_img2.imshow(img2, cmap='gray')
ax_img2.set_title('img2')
im = ax_corr.imshow(corr, cmap='viridis')
ax_corr.set_title('Cross-correlation')
ax_img1.plot(x, y, 'ro')
ax_img2.plot(x2, y2, 'go')
ax_corr.plot(x, y, 'ro')
fig.show()

绿点是img2 的中心。红点是放置绿点给出最大相关性的位置。

【讨论】:

  • 谢谢!你能解释一下为什么我们必须使用 2D 相关而不是 1D,即 numpy.correlate 吗?还有,为什么需要将灰度图像转换为“变成”2D?这种方法是否要求图像处于 RGB 或 RGBA 模式?
  • NumPy 的correlate 是一维的,所以我们不能在二维数据上使用它。对于图像,我的评论是模棱两可的......图像看起来灰度,甚至是二进制,但它实际上是 RGB。所以我把它减少到一个频道。这些图像(当时)处于 L 模式,我认为您需要调整方法以将 fftn 用于 RGB 或 RGBA 图像,但我不确定。
  • 你的代码有错误:注意x2, y2 = np.array(img2.shape) // 2,但实际上应该是y2, x2 = np.array(img2.shape) / /2 - 因为行对应于 y 坐标。
  • @yotabyte 很好,谢谢。如果我每次这样做都有一美元......
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-11-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-10-06
相关资源
最近更新 更多