Обнаружение похожих точек между двумя изображениями, а затем их наложение (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

какие идеи? Спасибо.

3 ответов


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

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

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

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


это должно быть сделано автоматически? На самом деле мне потребовалось некоторое время, чтобы сопоставить эти два изображения визуально, поэтому я думаю, что было бы очень трудно написать сценарий, который их выравнивает. Если вы собираетесь наложить несколько изображений (а не несколько сотен), я бы предложил сделать это вручную с помощью 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 и применить преобразования изображений самостоятельно, если хотите.


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