ベジェ曲線に合わせる必要のあるデータポイントのセット(間引くことができます)があります。精度よりもスピードが必要ですが、フィット感は認識できる程度に適切である必要があります。また、ライブラリをあまり使用しない、使用できるアルゴリズム(具体的にはNumPy)も探しています。
私はいくつかの研究論文を読みましたが、完全に実装するのに十分な詳細を持っているものはありません。オープンソースの例はありますか?
同様の問題があり、ベジェ曲線のあてはめについてGraphics Gems(1990)の「デジタル化された曲線を自動的に当てはめるアルゴリズム」を見つけました。それに加えて、私はその記事のソースコードを見つけました。
残念ながら、よくわからないCで書かれています。また、アルゴリズムを理解するのは非常に困難です(少なくとも私にとっては)。私はそれをC#コードに変換しようとしています。私が成功するなら、私はそれを共有しようとします。
基本的なベクトル操作関数が含まGGVecLib.c
れているのと同じフォルダ内のファイル。FitCurves.c
同様のStackOverflowの質問、手描きの曲線のスムージングを見つけました。承認された回答は、Graphic GemsのカーブフィッティングアルゴリズムのC#コードを提供します。
これらの回答の多くに欠けているのは、単一の 3 次ベジエ曲線をデータに当てはめたくないということです。より一般的には、3 次ベジエ曲線のシーケンス、つまり区分的な 3 次ベジエ フィットを任意のデータ セットに当てはめたいとします。
これを行うMATLABコードを備えた1995年の素晴らしい論文があります:
% Lane, Edward J. Fitting Data Using Piecewise G1 Cubic Bezier Curves.
% Thesis, NAVAL POSTGRADUATE SCHOOL MONTEREY CA, 1995
http://www.dtic.mil/dtic/tr/fulltext/u2/a298091.pdf
これを使用するには、少なくともノット ポイントの数、つまり最適化ルーチンがこれを適合させるために使用するデータ ポイントの数を指定する必要があります。必要に応じて、ノット ポイント自体を指定することもできます。これにより、近似の信頼性が向上します。論文は、かなり難しい例をいくつか示しています。Lane のアプローチは、3 次ベジエ セグメント間、つまり滑らかなジョイント間で G1 連続性 (隣接する接線ベクトルの方向が同一) を保証することに注意してください。ただし、曲率に不連続性がある場合があります (2 次導関数の方向の変化)。
コードを再実装し、最新の MATLAB (R2015b) に更新しました。ご希望の方はご連絡ください。
以下は、3 つのノット ポイント (コードによって自動的に選択される) のみを使用して、2 つの 3 次ベジエ セグメントをリサジュー図形に適合させる例です。
ほとんどのデータがモデルに適合する場合は、RANSACを試すことができます。4つのポイントをランダムに選択し、それらからベジェ曲線をフィットさせるのは簡単です。他のすべてのポイント(RANSACアルゴリズムの一部)に対して曲線を評価するのにどれほどの費用がかかるかは、頭から離れてわかりません。しかし、それは線形ソリューションであり、RANSACは本当に簡単に作成できます(そしておそらくオープンソースアルゴリズムがそこにあります)。
この問題に対する MATLAB ソリューションがありました。同じ問題が発生しましたが、私のコードは MATLAB で記述されています。それを Python に翻訳するのがそれほど難しくないことを願っています。
このコードでコントロール ポイントを見つけることができます 。
次の行に置き換えました。
[arclen,seglen] = arclength(p(:,1),p(:,2),'sp');
t = zeros(size(p,1),1);
sums = seglen(1);
for i = 2:size(p,1)-1
t(i) = sums / arclen;
sums = sums + seglen(i);
end
t(end) = 1;
arclengthの MATLAB コードは、こちらから取得できます。
その後、ベジエ曲線の制御点があり、制御点によるベジエ曲線の構築の実装がウェブ上にたくさんあります。
まず第一に、あなたが求めているものが実際にあなたが望んでいるものであることを確認してください。ポイントをベジエ曲線に合わせると、ポイントのハルに配置されます。スプラインを使用すると、曲線がすべての点を通過するようになります。
とはいえ、いずれかを描画する関数を作成することはまったく複雑ではありません。ウィキペディアには、ベジエ曲線の基本を説明する素晴らしい記事があります。