Skip to content

Commit

Permalink
Merge 5e2d0fa into 9b446ba
Browse files Browse the repository at this point in the history
  • Loading branch information
Rein van 't Veer committed Jun 28, 2019
2 parents 9b446ba + 5e2d0fa commit a7a318d
Show file tree
Hide file tree
Showing 4 changed files with 46 additions and 15 deletions.
23 changes: 23 additions & 0 deletions pyefd.py
Expand Up @@ -163,6 +163,29 @@ def calculate_dc_coefficients(contour):
return contour[0, 0] + A0, contour[0, 1] + C0


def reconstruct_contour(coeffs, locus=(0, 0), num_points=300):
t = np.linspace(0, 1.0, num_points)
# Append extra dimension to enable element-wise broadcasted multiplication
coeffs = coeffs.reshape(*coeffs.shape, 1)

orders = coeffs.shape[0]
orders = np.arange(1, orders + 1).reshape(-1, 1)
order_phases = 2 * orders * np.pi * t.reshape(1, -1)

xt_all = coeffs[:, 0] * np.cos(order_phases) + \
coeffs[:, 1] * np.sin(order_phases)
yt_all = coeffs[:, 2] * np.cos(order_phases) + \
coeffs[:, 3] * np.sin(order_phases)

xt_all = xt_all.sum(axis=0)
yt_all = yt_all.sum(axis=0)
xt_all = xt_all + np.ones((num_points,)) * locus[0]
yt_all = yt_all + np.ones((num_points,)) * locus[1]

reconstruction = np.stack([xt_all, yt_all], axis=1)
return reconstruction


def plot_efd(coeffs, locus=(0., 0.), image=None, contour=None, n=300):
"""Plot a ``[2 x (N / 2)]`` grid of successive truncations of the series.
Expand Down
1 change: 1 addition & 0 deletions requirements.txt
@@ -1 +1,2 @@
numpy
scipy
4 changes: 2 additions & 2 deletions setup.py
Expand Up @@ -13,7 +13,7 @@
import sys
from shutil import rmtree

from setuptools import find_packages, setup, Command
from setuptools import setup, Command

# Package meta-data.
NAME = 'pyefd'
Expand Down Expand Up @@ -91,7 +91,7 @@ def run(self):
author_email=EMAIL,
python_requires=REQUIRES_PYTHON,
setup_requires=['pytest-runner', ],
tests_require=['pytest', ],
tests_require=['pytest', 'scipy'],
url=URL,
keywords=["elliptic fourier descriptors", "fourier descriptors", "shape descriptors", "image analysis"],
py_modules=['pyefd'],
Expand Down
33 changes: 20 additions & 13 deletions tests.py
Expand Up @@ -17,6 +17,7 @@
import time

import numpy as np
from scipy.spatial.distance import directed_hausdorff

import pyefd

Expand Down Expand Up @@ -140,22 +141,28 @@ def test_locus():
np.testing.assert_array_almost_equal(locus, np.mean(contour_1, axis=0), decimal=0)


def test_fit_1():
n = 300
locus = pyefd.calculate_dc_coefficients(contour_1)
coeffs = pyefd.elliptic_fourier_descriptors(contour_1, order=20)
def test_reconstruct_simple_contour():
simple_polygon = np.array([[1., 1.], [0., 1.], [0., 0.], [1., 0.], [1., 1.]])
number_of_points = simple_polygon.shape[0]
locus = pyefd.calculate_dc_coefficients(simple_polygon)
coeffs = pyefd.elliptic_fourier_descriptors(simple_polygon, order=30)

reconstruction = pyefd.reconstruct_contour(coeffs, locus, number_of_points)
# with only 2 decimal accuracy it is a bit of a course test, but it will do
# directly comparing the two polygons will only work here, because efd coefficients will be cycle-consistent
np.testing.assert_array_almost_equal(simple_polygon, reconstruction, decimal=2)
hausdorff_distance, _, _ = directed_hausdorff(reconstruction, simple_polygon)
assert hausdorff_distance < 0.01

t = np.linspace(0, 1.0, n)
xt = np.ones((n,)) * locus[0]
yt = np.ones((n,)) * locus[1]

for n in pyefd._range(coeffs.shape[0]):
xt += (coeffs[n, 0] * np.cos(2 * (n + 1) * np.pi * t)) + \
(coeffs[n, 1] * np.sin(2 * (n + 1) * np.pi * t))
yt += (coeffs[n, 2] * np.cos(2 * (n + 1) * np.pi * t)) + \
(coeffs[n, 3] * np.sin(2 * (n + 1) * np.pi * t))
def test_larger_contour():
locus = pyefd.calculate_dc_coefficients(contour_1)
coeffs = pyefd.elliptic_fourier_descriptors(contour_1, order=50)
number_of_points = contour_1.shape[0]

assert True
reconstruction = pyefd.reconstruct_contour(coeffs, locus, number_of_points)
hausdorff_distance, _, _ = directed_hausdorff(contour_1, reconstruction)
assert hausdorff_distance < 0.4


def test_performance():
Expand Down

0 comments on commit a7a318d

Please sign in to comment.