Есть ли способ вычислить остатки при попытке сопоставить функцию с изображением в python?

#python #image-processing #numerical-analysis

#питон #обработка изображений #численный анализ

Вопрос:

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

Я использую scipy.minimize.optimize его, чтобы попытаться подогнать кривую к изображению. Моя стратегия состоит в том, чтобы измерить, насколько хорошо мой объект, который сегментирован в B приведенной ниже матрице, соответствует моей функции f , минимизируя среднее евклидово расстояние между B и f .

Я определил следующую функцию, которую я передаю в scipy.optimize.minimize :

 # x is a tuple of arguments passed to f
# f is the function I am trying to fit to B, which returns a matrix of 0s and 1s
# B is the image I am trying to fit to, whose voxel values are 0 or 1

from scipy.ndimage.morphology import distance_transform_edt
def objective(x, f, B):
    f_matrix = f(*x)
    f_matrix_edt = distance_transform_edt(f_matrix)
    residuals = B * f_matrix_edt
    return residuals.sum()
 

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

Ответ №1:

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

 from scipy.ndimage.morphology import distance_transform_edt
from skimage.morphology import skeletonize
def objective(x, f, B):
    f_matrix = f(*x)
    B_skeleton = skeletonize(B)
    B_edt = distance_transform_edt(B_skeleton)
    residuals = f_matrix * B_edt ** 2
    return residuals.sum()
 

Это дало довольно хорошие результаты!