检测两张图片之间的相似点然后叠加它们(Python)

时间:2016-03-08 20:16:49

标签: python scikit-image

我有两张相同神经切割的图片,深度略有不同,每个切片上使用不同的染料进行染色。我想覆盖这两个图像,但它们在幻灯片/照片上没有完全对齐,只是为了做到这一点。我想要做的是编写代码,检测两个切片之间的相似形状(即相同的单元格),然后根据这些单元格的位置覆盖图片。有没有办法做到这一点?

我到目前为止的代码是:

import matplotlib
import matplotlib.pyplot as plt
import matplotlib.image as mpimg
import numpy as nb
from skimage import data, io, filters
import skimage.io
from PIL import Image
from scipy import misc
import numpy as np
from skimage.transform import resize 
%matplotlib inline

picture1 = "Images/294_R_C3_5" # define your image pathway

i1 = Image.open(picture1 + ".jpg").convert('L') # open your first image and convert it to greyscale
i1 = i1.point(lambda p: p * 5) # brighten the image
region=i1.crop((600,0, 4000, 4000)) # crop the image
region.save(picture1 + ".png", "PNG") # save the cropped image as a PNG

i1 = matplotlib.image.imread(picture1 + ".png", format=None) # print the new cropped image
io.imshow(i1)
io.show()    

image1

I1 = Image.open(picture1 + ".png") # reopen your image using a different module
I1

image2

picture2 = "Images/294_R_B3_6" #define your image pathway
i2 = Image.open(picture2 + ".jpg").convert('L') # open your second image and convert it to greyscale
i2 = i2.point(lambda p: p * 5)
region=i2.crop((600,0, 4000, 4000)) # crop the image
region.save(picture2 + ".png", "PNG") # save the cropped image as a PNG

i2 = matplotlib.image.imread(picture2 + ".png", format=None) # print the new cropped image
io.imshow(i2)
io.show()

image3

I2 = Image.open(picture2 + ".png") # open your image using a different module
I2     

image4

我尝试过使用skimage,但似乎它收集了太多积分。另外,我不知道如何根据这些点堆叠图像。这是我的代码:

from skimage.feature import ORB
orb = ORB(n_keypoints=800, fast_threshold=0.05)

orb.detect_and_extract(i1)
keypoints1 = orb.keypoints
descriptors1 = orb.descriptors

orb.detect_and_extract(i2)
keypoints2 = orb.keypoints
descriptors2 = orb.descriptors

from skimage.feature import match_descriptors
matches12 = match_descriptors(descriptors1, descriptors2, cross_check=True)

from skimage.feature import plot_matches
fig, ax = plt.subplots(1, 1, figsize=(12, 12))

plot_matches(ax, i1, i2, keypoints1, keypoints2, matches12)

ax.axis('off');    

image5

然后我尝试将其清理一下,但这比我想要的要多得多:

from skimage.transform import ProjectiveTransform
from skimage.measure import ransac

src = keypoints1[matches12[:, 0]][:, ::-1]
dst = keypoints2[matches12[:, 1]][:, ::-1]

module_robust12, inliers12 = ransac((src, dst), ProjectiveTransform, min_samples=4, residual_threshold=1, max_trials=300)

fig, ax = plt.subplots(1, 1, figsize=(12, 12))

plot_matches(ax, i1, i2, keypoints1, keypoints2, matches12[inliers01])

ax.axis('off');    

image6

有什么想法吗?谢谢。

4 个答案:

答案 0 :(得分:5)

这种问题经常出现在计算机视觉中。自动执行与全景拼接完全相同的问题。你基本上需要做的就是你已经完成了什么:

  1. 提取要素点(您正在使用ORB要素 - SIFT可能会为您提供更好的结果,如果重要的话,它只是一个非自由算法)及其描述符
  2. 匹配他们
  3. 使用RANSAC过滤它们
  4. 计算两组点之间的单应性
  5. 做拼接
  6. 我从未使用skimage进行特征提取/处理,但您的管道看起来很好。我还发现了这个可爱的(由作者写的)图像拼接指南,你会觉得非常有用! https://github.com/scikit-image/scikit-image-paper/blob/master/skimage/pano.txt

    它基本上完成了你所做的一半,并完成了接下来的步骤!

答案 1 :(得分:2)

是否必须自动完成?实际上,我花了一些时间来直观地关联这两个图像,所以我认为编写一个对它们进行对比的脚本真的很难。如果您要覆盖多个图像(不是几百个),我建议您使用hugin panorama stitcher手动执行此操作。它会节省你的努力。

我试图解决你的问题,我花了不到10分钟才找到相似之处,手动放置控制点,然后导出图像。

Control points in hugin

这就是你想要的吗?

我使用hugin的遮罩功能来指定最终重映射图像中应该可见的图像,并使用不同的遮罩导出全景两次。

更新

Hugin项目文件pgrep是一个纯文本文件,其中包含应用于它们的图像名称和转换,如下所示:

.pto

如果您愿意,可以使用re并自己应用图像转换来解析这个问题。

答案 2 :(得分:0)

我能够通过斐济找到一个非常有用的插件(是ImageJ),名为" Template_Matching" (可以找到here)使用堆叠图像层和参考点。这个工具是最容易使用的工具之一,也是我能找到的最好的工具之一。

答案 3 :(得分:0)

您需要的一切:

  • ORB->查找稳定点
  • 匹配点
  • 单应性
  • 变形图像

https://www.learnopencv.com/image-alignment-feature-based-using-opencv-c-python/