拟合两个重叠圆圈的图像

时间:2016-12-16 04:23:06

标签: python scipy

我正在尝试拟合两个重叠圆的2D图像,其中一个圆圈完全由1个组成,另一个圆圈完全由零组成。以下是最低工作示例。

curve_fit似乎根本不做任何拟合,只返回初始猜测。我开始尝试只为一个圆圈拟合一个参数,但最后,我想拟合所有参数:两个圆心的位置和每个圆的半径。

非常感谢任何帮助。感谢。

%matplotlib inline

import numpy as np
import matplotlib.pyplot as plt

from scipy.optimize import curve_fit

def overlapping_circles((x, y), x0, y0, r0, x1, y1, r1):
    img = np.zeros_like(x)

    img[np.sqrt((x - x0)**2 + (y - y0)**2) <= r0] = 1.
    img[np.sqrt((x - x1)**2 + (y - y1)**2) <= r1] = 0.

    return img.ravel()

size = 100.
# Create x and y indices
x = np.linspace(0, size-1, size)
y = np.linspace(0, size-1, size)
x, y = np.meshgrid(x, y)
x0, y0 = size/2., size/2.
r0 = 30.
x1, y1 = size/2., size/4.
r1 = 30.
img = overlapping_circles((x, y), x0, y0, r0, x1, y1, r1)
plt.imshow(img.reshape(size, size), interpolation='none')

popt, pcov = curve_fit(lambda (x,y), guess_x0: overlapping_circles((x,y), guess_x0, y0, r0, x1, y1, r1), (x, y), img, p0=x0/2.)
print(popt, x0/2.)

重叠圆圈:

Overlapping circles

感谢lucianopaz提供可行的解决方案。我已经粘贴了代码,实现了为后代使用暴力的建议。

%matplotlib inline

import numpy as np
import matplotlib.pyplot as plt

from scipy.optimize import brute

def overlapping_circles((x, y), x0, y0, r0, x1, y1, r1):
    img = np.zeros_like(x)

    img[np.sqrt((x - x0)**2 + (y - y0)**2) <= r0] = 1.
    img[np.sqrt((x - x1)**2 + (y - y1)**2) <= r1] = 0.

    return img.ravel()

def residuals((x, y), x0, y0, r0, x1, y1, r1, img):
    return np.sum((overlapping_circles((x, y), x0, y0, r0, x1, y1, r1) - img.ravel())**2.)

size = 100.
# Create x and y indices
x = np.linspace(0, size-1, size)
y = np.linspace(0, size-1, size)
x, y = np.meshgrid(x, y)
x0, y0 = size/2., size/2.
r0 = 30.
x1, y1 = size/2., size/4.
r1 = 30.
img = overlapping_circles((x, y), x0, y0, r0, x1, y1, r1)
plt.imshow(img.reshape(size, size), interpolation='none')

simplified_residuals = lambda fit_x0: residuals((x, y), fit_x0[0], fit_x0[1], r0, x1, y1, r1, img)

rranges = (slice(0, 100, 1), slice(0, 100, 1))
resbrute = brute(simplified_residuals, rranges, full_output=True, finish=None)
print(resbrute[0], x0, y0)

1 个答案:

答案 0 :(得分:1)

您对curve_fit的实施是正确的,只有一点点评论,我认为xy应该被拉平并放入数组,因为{{ 3}}说自变量应该是:

  

具有k个预测变量的函数的M长度序列或(k,M)形数组。测量数据的自变量。

但是,我认为你的问题并不存在,但是因为函数overlapping_circles条件不好而发生了。它不可微分,因为参数的微小变化可能导致img由于img的像素离散而没有变化。为了改善拟合,你应该使用不使用jacobians的方法,也不使用函数最小化的hessians,并且这些方法适用于条件差,不可微分的问题。我建议你看看docsherehere。当然,对于您的问题,使用here方法粗略估计参数可能很有用。