Вопрос: Обнаружение похожих точек между двумя картинками, а затем их наложение (Python)


У меня есть две фотографии одного и того же нерва, вырезанные на немного разных глубинах, где для окрашивания на каждом срезе использовался другой краситель. Я хотел бы наложить два изображения, но они не идеально выровнены на слайде / фотографии, чтобы сделать это просто. Я хочу написать код, который обнаруживает похожие фигуры (т. Е. Те же ячейки) между двумя срезами, а затем накладывает изображения на основе позиционирования этих ячеек. Есть ли способ сделать это?

Код, который у меня есть до сих пор:

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 

Есть идеи? Спасибо.


6


источник


Ответы:


Этот вопрос часто возникает в компьютерном видении. Сделать это автоматически - та же самая проблема, что и сложение панорамы. То, что вам в основном нужно сделать, это то, что вы почти закончили:

  1. Извлечь функциональные точки (вы используете функции ORB - SIFT может дать вам лучшие результаты, это просто беспроблемный алгоритм, если это имеет значение) и их дескрипторы
  2. Сопоставить их
  3. Используйте RANSAC для их фильтрации
  4. Вычислить гомографию между двумя наборами точек
  5. Сделайте строчку

Я никогда не использовал skimage для извлечения / обработки функций, но ваш трубопровод выглядит неплохо. Я также нашел этот прекрасный (по-авторам-skimage) путеводитель для сшивки изображений, который вы найдете очень полезным! https://github.com/scikit-image/scikit-image-paper/blob/master/skimage/pano.txt

Это в основном делает половину того, что вы сделали, и проходит следующие шаги!


5



Нужно ли это делать автоматически? На самом деле мне потребовалось некоторое время, чтобы визуально сопоставить эти два изображения, поэтому я думаю, что было бы очень сложно написать сценарий, который их выравнивает. Если вы собираетесь наложить несколько изображений (не несколько сотен), я бы предложил сделать это вручную с помощью hugin panorama stitcher , Это сэкономит ваши усилия.

Я попытался решить вашу проблему, и мне потребовалось меньше 10 минут, чтобы найти сходство, вручную разместить контрольные точки и экспортировать изображения.

Контрольные точки в hugin

Это то, что вы хотите?

Я использовал функцию маскирования hugin, чтобы указать, какое изображение должно быть видимым в окончательном перепрограммированном изображении, и дважды экспортировать панораму с различными масками.

Обновить

Файл проекта Hugin .pto представляет собой текстовый файл, который содержит имена и преобразования изображений, применяемые к ним, например:

# image lines
#-hugin  cropFactor=1
i w3400 h4000 f0 v1.99999941916805 Ra0 Rb0 Rc0 Rd0 Re0 Eev0 Er1 Eb1 r0.00641705670350258 p0.588362807000514 y-0.252729475162748 TrX0 TrY0 TrZ0 j0 a0 b0 c0 d0 e0 g0 t0 Va1 Vb0 Vc0 Vd0 Vx0 Vy0  Vm5 n"SQNrnTw.png"

Вы можете проанализировать это с помощью Python, используя re и применить преобразования изображений самостоятельно, если хотите.


2



Я смог найти очень полезный плагин через Fiji (был ImageJ) под названием «Template_Matching» (его можно найти Вот ), который использует слои сложенного изображения и точку отсчета. Этот инструмент является одним из самых простых в работе и является лучшим, что я смог найти.


0