У меня была очень похожая проблема с вашей, когда я пытался центрировать круглые объекты как на изображениях КТ, так и на МР - и проходил различные маршруты с регистрацией, грубыми преобразованиями и т. Д. надежный.
В итоге я использовал гораздо более простой, более надежный и гораздо более быстрый подход, отступив назад и подумав об этом по-другому.
У вас есть два круга на изображении, и вы хотитенайти местоположение и масштаб.
- Итак, сначала получите два одномерных профиля вашего изображения - один в строках и один в столбцах. Ваш объект - это круг, поэтому в результате получатся два гауссовских профиля. Это простая нарезка массива со средним значением, поэтому она очень быстрая:
# 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)
Из квадратного профиля легко вычислить ребра, а разница между местоположениями двух ребер дает вам диаметр.
Итак, в результате вы получите центр и диаметркруг.
Я использую этот подход, чтобы делать то, что вы делаете - местоположение и размер кругового профиля - как в КТ, так и в МР. В итоге он оказался как минимум на порядок быстрее, чем все остальное, и гораздо более надежным.