Вычисление преобразования с помощью круга и линий - PullRequest
4 голосов
/ 26 октября 2019

Я пытаюсь определить трансформацию (вращение + сдвиг + масштаб) между двумя изображениями, чтобы сместить их.

Изображения взяты с двумя разными способами, которые дают очень разные текстуры. Поэтому я не могу использовать методы, основанные на поддержании оптического потока. Я подумал, что было бы неплохо портировать изображения для извлечения геометрии (см. Пример ниже). Но потом у меня возникают проблемы с просмотром того, что я могу сделать ... может быть, извлечь вертикальные линии и центральный круг, чтобы помочь мне извлечь мое преобразование.

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

enter image description here

--- РЕДАКТИРОВАТЬ ПОЗЖЕ ---

Я обнаружил окружность и линии с помощью преобразования Хафа(см. рисунок ниже). Действительно, это поможет для правильной регистрации. Тем не менее, какой инструмент на Python я могу использовать для регистрации этих элементов? Я часто использую оптическое сохранение потока, но в этом случае это довольно сложно ...

enter image description here

Ответы [ 3 ]

4 голосов
/ 03 ноября 2019

Найдите не менее 4 неколлинеарных соответствующих точек:

  1. Центр диска
  2. Найдите ближайшие точки на боковых линиях к центру диска (как минимум 2 соответствующие точки будутрассчитано). Он находится на линии, перпендикулярной боковым линиям через центр диска (используйте этот метод ).
  3. Найдите параллельные линии боковых линий через центр диска ( this может помочь) и вычислить точку пересечения этих линий и области диска ( может помочь )

Затем вы можете использовать findHomography для вычисления гомографииМатрица, которая является преобразованием между двумя изображениями.

Пример кода похож на следующий:

# Read the first image.
im_fst = cv2.imread('img1.jpg')
# Four points in the first image (more is better)
pts_fst = np.array([[141, 131], [480, 159], [493, 630],[64, 601]])

# Read the second image.
im_scd = cv2.imread('img2.jpg')
# Four points in the second image
pts_scd = np.array([[318, 256],[534, 372],[316, 670],[73, 473]])

# Calculate Homography
h, status = cv2.findHomography(pts_fst, pts_scd)

# Warp source image to destination based on homography
im_out = cv2.warpPerspective(im_fst, h, (im_scd.shape[1],im_scd.shape[0]))
2 голосов
/ 27 октября 2019

Если шаблон всегда представляет собой диск внутри дорожки, с чистой бинаризацией это выглядит как простая проблема.

Вы можете надежно и точно получить центр и площадь диска, а значит и радиус. Из боковых пятен вы можете найти вертикали (Hough, или линию, подходящую к внутреннему сечению контуров, или просто линию через пары удаленных точек).

Тогда вы получите масштаб из отношения радиусов,или соотношение расстояний между линиями. Угол поворота задается направлением вертикалей. И перевод по координатам центра.

На самом деле, у вас слишком много данных для решения для 4-х степеней свободы, и есть несколько возможных разрешений. В зависимости от того, как именно создаются эти изображения, вы должны использовать самые надежные фрагменты информации.

enter image description here

0 голосов
/ 16 ноября 2019

У меня была очень похожая проблема с вашей, когда я пытался центрировать круглые объекты как на изображениях КТ, так и на МР - и проходил различные маршруты с регистрацией, грубыми преобразованиями и т. Д. надежный.

В итоге я использовал гораздо более простой, более надежный и гораздо более быстрый подход, отступив назад и подумав об этом по-другому.

У вас есть два круга на изображении, и вы хотитенайти местоположение и масштаб.

  1. Итак, сначала получите два одномерных профиля вашего изображения - один в строках и один в столбцах. Ваш объект - это круг, поэтому в результате получатся два гауссовских профиля. Это простая нарезка массива со средним значением, поэтому она очень быстрая:
    # r/c 1/0 are variables you can use to set limits on which areas of
    # the image you want to limit the search to, or you can use the entire
    # image size
    r0 = c0 = 0
    r1, c1 = image.shape
    r_prof = np.mean(image[r0:r1, :], axis=0)
    c_prof = np.mean(image[:, c0:c1], axis=1)
Найдите центральную точку этих гауссовых профилей. Это легко с любыми алгоритмами поиска пиков. Это дает вам центр вашего круга.
    # find_peak is a function to find the peak index in a profile
    circle_r = find_peak(r_profile)
    circle_c = find_peak(c_profile)
Чтобы найти масштаб, вам нужно найти размер круга. Чтобы сделать это, просто заново сделайте профили изображения, но на этот раз строка / столбец сузятся до одного пикселя в центре круга, который вы получили выше. Это даст вам довольно квадратный профиль.
    # get single pixel width profile across center of circle
    r_prof = np.mean(image[circle_r, :], axis=0)
    c_prof = np.mean(image[:, circle_c], axis=1)
Из квадратного профиля легко вычислить ребра, а разница между местоположениями двух ребер дает вам диаметр.

Итак, в результате вы получите центр и диаметркруг.

Я использую этот подход, чтобы делать то, что вы делаете - местоположение и размер кругового профиля - как в КТ, так и в МР. В итоге он оказался как минимум на порядок быстрее, чем все остальное, и гораздо более надежным.

...