2012-01-03 11 views
11

PHPで波形をレンダリングするときに、ラメインエンコーダを使ってダウンサンプリングし、結果のデータポイントから波形を描画します。私がやりたい何PHPのレンダリング波形 - より圧縮されたレンダリングを作成するには?

enter image description here

は、波形の見かけ上のダイナミックレンジは、本質的に「圧縮」であるように、私のコードを変更している:私は現在、このような画像を取得しています。実際の振幅がされた状態で

// draw this data point 
      // relative value based on height of image being generated 
      // data values can range between 0 and 255 
      $v = (int) ($data/255 * $height); 


      // don't print flat values on the canvas if not necessary 
      if (!($v/$height == 0.5 && !$draw_flat)) 
      // draw the line on the image using the $v value and centering it vertically on the canvas 
      imageline(
       $img, 
       // x1 
       (int) ($data_point/DETAIL), 
       // y1: height of the image minus $v as a percentage of the height for the wave amplitude 
       $height * $wav - $v, 
       // x2 
       (int) ($data_point/DETAIL), 
       // y2: same as y1, but from the bottom of the image 
       $height * $wav - ($height - $v), 
       imagecolorallocate($img, $r, $g, $b) 
      );  

- :次のように私は、現在、各データポイントの高さをレンダリングするために使用しています

enter image description here

式は、もっとこのようになります波形を生成するために、このコードの最初の行で定義されています。 -

$v = (int) ($data/255 * $height); 

残念ながら私の数学スキルは悪いです。私がしなければならないことは、本質的に$ vの値に「曲線」を適用することで、方程式に入力された数値が低いほど、結果の出力は高くなり、入力数が増加すると、方程式は最終的に入力が255に達すると出力も255になります。また、入力が0の場合は出力も0になります。

これがはっきりしない場合はお詫びしますが、私の限られた数学の経験と明確に結びついています。

おそらく、視覚的な表現は私の意図を説明役立つだろう: -

enter image description here

$ vの値が0または255式の出力があるべき正確に入力(0または255)のいずれかである場合には。ただし、入力が中間の値である場合は、上の曲線の出力に従う必要があります。 (上記は説明するだけでラフ描いていた。)

EDIT:

次のようになり、私は今の波形を生成していますAlnitiks 'POW' 関数のソリューションに基づいて: -

enter image description here

$ v変数の置換式を次のように使用します。 -

私は0.4の値を上げようとしましたが、結果はstです。意図したとおりのものではありません。

EDIT 2:

にここに要求されたように、私の$データ変数の生datadumpです:

Raw Data

これは、波形を描画するために使用される前に$ Vを返すために式に渡されます(私が上に投稿した元のコードで変数$ vに何ができるかを見ることができます)$ heightは単純にピクセル数が高く、レンダリングするイメージを設定しました。

このデータはカンマで区切られた値のリストです。私はこれが役立つことを願っています平均値が128であるというあなたの主張が正しいと思われます。これまでのところ私はあなたの訂正のために頭を尽くすことができませんでした。私は現在の理解を少し超えているのではないかと心配しています。 (迅速な表示があると便利だろうと)無数学のスキルを持つ

+1

+1:これは厳密にトピックであるかどうかはわかりませんが、気にしません...楽しいです! –

+0

本当にその曲線の方程式を見つけて、乗算係数を適用する必要があります。これはすべて、あなたが楽しい要素を取り除くときまで沸騰します。そして、それを完全にスキップして分数値(おそらくそう思われる)を気にしない場合は、既知の値の検索を手動で作成することができます。 –

+1

確かに。私はこれが数学サイトに掲載されるべきかどうか疑問に思いました。しかし、私はあなたから得られる回答は、数学者よりも自分の言語ではるかに多くなると確信しています。 :-) – gordyr

答えて

3

あなたは256の可能な値を持っています。 、あなたは簡単に動的な値を得ることができます行わ

$dynamic = array(
    0 => 0, 
    1 => 2, 
    ... 
); 

$v = (int) ($dynamic[(int) $data/255] * $height); 

をあなたには、いくつかの精度を失うかもしれないが、それはおそらくだこれらの値のそれぞれについて、「ダイナミック」の値を含む配列を作成します。有用。


自然の動的な値は、数学sine及び余弦関数によって生成されたPHPこのsin­Docs(およびその他が連結)されています。

あなたは事前に計算した値を持っているので、配列を、同様の配列を事前入力して再使用するためにループし、その機能を使用することができます。

$sine = function($v) 
{ 
    return sin($v * 0.5 * M_PI); 
}; 

$dynamic = array(); 
$base = 255; 
for ($i = 0; $i <= $base; $i++) 
{ 
    $dynamic[$i] = $i/$base; 
} 

$dynamic = array_map($sine, $dynamic); 

あなたが書くことができますので、私は、ここに変数関数を使用しますあなたのニーズに合ったものを簡単にテストすることができます。

+0

ありがとう、あらかじめ定義された配列は確かに最も簡単な解決策になるでしょう。他のすべてが失敗した場合、これは私が取る方法です。しかし、私はむしろ、簡単な方程式(必要に応じて最終的に修正が可能)を行い、現在はサイン/コサインの提案を調べています。再度、感謝します。 – gordyr

+0

サインについては、xがi/255 * 0.5 * PIからiが0-255になるように見えます。あなたのカーブを与えるかもしれません。例を追加します。 – hakre

+0

すばらしい答えhakre多くのありがとう。あなたの例は、私が必要とするものを正確に行います。ちなみに、Alnitakの提案したように、私はpow関数を使ってほぼそこに着いた。私は彼の方法もうまくいくと確信していますが、時間をかけて例を挙げると答えが必要です。すべての人に大きな感謝。 :-) – gordyr

3

ガンマ補正と同様のものが必要です。

入力値xが0.0 - > 1.0の場合、nが0.2〜0.7(ish)の範囲にあるときは、y = pow(x, n)とします。目的のカーブを与える数値を選択するだけです。

値が0〜255の範囲にあるため、255.0で除算し、pow関数を適用してから255を再度掛ける必要があります。

$y = 255 * pow($x/255.0, 0.4); 

pow式は、それ自体に、0と1の地図基準を満たす、より小さな値は大きな値よりも「増幅」されています。

ここでN = 1/1.6、1/2,1/2.4〜1/2.8のガンマ曲線を示すグラフで、対(赤色)sinカーブの下部

Gamma Curves vs Sin

nの値では、ローエンドに「圧縮」が多く適用されるため、明るい青色の線はn = 1/2.8の線です。

sinのカーブは0から0.5の範囲でほぼ線形であるため、ローエンド圧縮はほとんどありません。

私は自分の価値観が実際に128を中心としている疑いがあるとして場合は、多少の計算式を変更する必要があります

$v = ($x - 128.0)/128.0; 
$y = 128 + 127 * sign($v) * pow(abs($v), 0.4); 

私はthe PHP developers have notはPHPライブラリでsign機能が含まれていることがわかりけれども。

+0

ありがとうAlnitak、私は現在hakreと自分の提案の両方を見ています。 (サイン/コサインとそれぞれのpow関数)答えに感謝しています。できれば私はこれをすぐに答えられるようにする必要があります。 :-) – gordyr

+0

これは素晴らしい情報ですAlnitak。ありがとうございました。それは実際より良い全体的なソリューションのように見えます。しかし何らかの理由で私はイメージを正しくレンダリングするのに問題があります。あなたの答えの実装には何か問題があるはずです。私は試し続けて報告します。 – gordyr

+0

@ gordyrは、あなたの値の一部が負であるか、おそらくゼロの値128に基づいていますか? – Alnitak

関連する問題