【问题标题】:Fit Points With a Smooth Curve用平滑曲线拟合点
【发布时间】:2017-01-02 21:18:59
【问题描述】:

我想在 python 中用 smooth 曲线拟合图像上的一组点。曲线可以是开放的或封闭的。此外,我想将绘制在图像上的曲线作为与图像具有相同大小的蒙版。有没有我可以参考的模块或功能?谢谢。

【问题讨论】:

  • 在我看来,平滑总是意味着平均。因此,您将获得较少的积分。当您使用移动平均线时,第一点的数据将丢失。要解决您的问题,您必须对数据进行拟合(高阶多项式?取决于数据的外观),然后评估原始曲线中所有点的拟合函数。
  • 参见 approxPolyDp 函数。或者看看(必要时插值)样条线。
  • @nostradamus 很抱歉让您感到困惑。实际上我的意思是用平滑曲线连接一组点。它们不是必需的数据点。

标签: python opencv matplotlib computer-vision scikit-image


【解决方案1】:

这通常称为参数插值。有一个名为splprep 的 scipy 函数。您要求的步骤是:

1) 平滑形状(用有序点构建,如果不先使用convex hull,请检查this question)。

注意:更多关于如何在图像检查上创建形状this question

2) 使用平滑形状在图像上构建遮罩(比如说二维数组)。

以下配方可以做到这一点:

import numpy as np
from scipy.interpolate import splprep, splev
import matplotlib.pyplot as plt
from matplotlib import path

# Building a shape with scattered points.
x = np.array([10, 10, 0, 0, 10, 10, 20, 20, 30, 30, 20, 20, 10]) + 10
y = np.array([0, 10, 10, 20, 20, 30, 30, 20, 20, 10, 10, 0, 0]) + 10
image = np.random.randint(0, 10, (50, 50))

# Smoothing the shape.
# spline parameters
s = 3.0 # smoothness parameter
k = 2 # spline order
nest = -1 # estimate of number of knots needed (-1 = maximal)
t, u = splprep([x, y], s=s, k=k, nest=-1)
xn, yn = splev(np.linspace(0, 1, 500), t)

# Showing the original shape
plt.imshow(image.T, origin='lower', interpolation='nearest', cmap='gray')
plt.plot(x, y, color='b', linewidth=3)
plt.xlim(0, 50)
plt.ylim(0, 50)
plt.show()

# Showing the original shape vs smooth shape
plt.imshow(image.T, origin='lower', interpolation='nearest', cmap='gray')
plt.plot(x, y, color='b', linewidth=3)
plt.plot(xn, yn, color='r', linewidth=3)
plt.xlim(0, 50)
plt.ylim(0, 50)
plt.show()

# Changing values inside the shape (and outside). Building a boolean mask.
image1 = image.copy()
image2 = image.copy()
mask = np.zeros(image.shape)
xx, yy = np.meshgrid(range(image.shape[0]),range(image.shape[1]))
shapes = np.hstack((xn[:, np.newaxis], yn[:, np.newaxis]))
p = path.Path(shapes)
for i in range(image.shape[0]):
    for j in range(image.shape[1]):
        if not p.contains_point((i, j)):
            image1[i, j] = 0
            mask[i, j] = True
        else:
            image2[i, j] = 0

# Showing changes in image for values outside shape.
plt.imshow(image1.T, origin='lower', interpolation='nearest', cmap='gray')
plt.plot(xn, yn, color='r', linewidth=3)
plt.xlim(0, 50)
plt.ylim(0, 50)
plt.show()

# Showing changes in image for values inside shape.
plt.imshow(image2.T, origin='lower', interpolation='nearest', cmap='gray')
plt.plot(xn, yn, color='r', linewidth=3)
plt.xlim(0, 50)
plt.ylim(0, 50)
plt.show()

对代码进行了注释,以便您了解每个结果图中发生的情况:

1. 简单的形状覆盖图像

2. 图像上的简单与平滑形状

3. 在形状内使用值

4. 使用形状外的值

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-10-18
    • 1970-01-01
    • 2017-08-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多