Commit cf0c86fa authored by Stephen Thompson's avatar Stephen Thompson

Changed scipy.leastsq to scipy.least_squares so we can use bounded optimisation

parent 253a2a55
Pipeline #2406 failed with stages
in 25 minutes and 58 seconds
......@@ -33,7 +33,7 @@ Example usage:
::
python sksurgeryspherefitting.py polydata_in.vtp --output polydatata_in.vtp
python sksurgeryspherefitting.py polydata_in.vtp --output polydatata_out.vtp
It was created in part to provide a simple demonstration of algorithm development as part of a
program of SNAPPY Tutorials, but also provides a useful service should you want to fit a sphere
......
......@@ -2,10 +2,13 @@
""" Module for fitting a sphere to a list of 3D points """
#scipy has a nice least squares optimisor
from scipy.optimize import leastsq
from scipy.optimize import least_squares
import numpy
def fit_sphere_least_squares(x_values, y_values, z_values, initial_parameters):
def fit_sphere_least_squares(x_values, y_values, z_values, initial_parameters,
bounds=
((-numpy.inf, -numpy.inf, -numpy.inf, -numpy.inf),
(numpy.inf, numpy.inf, numpy.inf, numpy.inf))):
"""
Uses scipy's least squares optimisor to fit a sphere to a set
of 3D Points
......@@ -17,8 +20,9 @@ def fit_sphere_least_squares(x_values, y_values, z_values, initial_parameters):
coordinates.
:param: an array containing four initial values (centre, and radius)
"""
return leastsq(_calculate_residual_sphere, initial_parameters,
args=(x_values, y_values, z_values))
return least_squares(_calculate_residual_sphere, initial_parameters,
bounds=bounds,
args=(x_values, y_values, z_values))
def _calculate_residual_sphere(parameters, x_values, y_values, z_values):
"""
......
......@@ -23,8 +23,8 @@ def run_demo(model_file_name, output=""):
if output != "":
sphere = vtk.vtkSphereSource()
sphere.SetCenter(result[0][0], result[0][1], result[0][2])
sphere.SetRadius(result[0][3])
sphere.SetCenter(result.x[0], result.x[1], result.x[2])
sphere.SetRadius(result.x[3])
sphere.SetThetaResolution(60)
sphere.SetPhiResolution(60)
......
......@@ -9,15 +9,6 @@ import six
# Pytest style
#def test_using_pytest_sksurgeryspherefitting():
# x = 1
# y = 2
# verbose = False
# multiply = False
# expected_answer = 3
# assert run_demo(x, y, multiply, verbose) == expected_answer
def test_fit_sphere_least_squares():
x_centre = 1.0
......@@ -51,8 +42,8 @@ def test_fit_sphere_least_squares():
parameters = [0.0, 0.0, 0.0, 0.0]
result = sphere_fitting.fit_sphere_least_squares (xs, ys, zs, parameters)
numpy.testing.assert_approx_equal (result[0][0], x_centre, significant = 10)
numpy.testing.assert_approx_equal (result[0][1], y_centre, significant = 10)
numpy.testing.assert_approx_equal (result[0][2], z_centre, significant = 10)
numpy.testing.assert_approx_equal (result[0][3], radius, significant = 10)
numpy.testing.assert_approx_equal (result.x[0], x_centre, significant = 10)
numpy.testing.assert_approx_equal (result.x[1], y_centre, significant = 10)
numpy.testing.assert_approx_equal (result.x[2], z_centre, significant = 10)
numpy.testing.assert_approx_equal (result.x[3], radius, significant = 10)
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment