【发布时间】:2012-02-01 14:35:04
【问题描述】:
我在 PHP 中渲染一个波形,方法是使用 lame 编码器对其进行下采样,然后从结果数据点中绘制波形。我目前收到这样的图像:
我想做的是修改我的代码,以便波形的明显动态范围基本上被“压缩”。要生成看起来更像这样的波形:
我目前用来渲染每个数据点高度的公式如下:-
// 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)
);
实际幅度由该代码的第一行定义:-
$v = (int) ( $data / 255 * $height );
不幸的是,我的数学能力很差。我需要做的基本上是对 $v 的值应用“曲线”,这样当输入到方程中的数字较低时,结果输出较高,并且随着输入数字的增加,方程会减少放大,直到最后输入达到255,输出也应该是255。曲线也应该是这样的,输入为0,输出也为0。
如果不清楚,我深表歉意,但由于我有限的数学经验,我发现这个问题很难表达。
也许视觉表示将有助于描述我的意图:-
当 $v 的值为 0 或 255 时,等式的输出应该正好是输入(0 或 255)。但是,当输入是介于两者之间的值时,它应该遵循上面曲线的结果输出。 (以上只是一个粗略的图来说明。)
编辑:
基于 Alnitiks 'pow' 函数解决方案,我现在正在生成如下所示的波形:-
使用 $v 变量的替换方程如下:-
$v = pow($data / 255.0, 0.4) * $height;
我已经尝试提高 0.4 的值,但结果仍然不符合预期。
编辑 2:
这里要求的是我的 $data 变量的原始数据转储:
在用于绘制波形之前,这被传递到方程中以返回 $v(您可以在上面发布的原始代码中看到我对变量 $v 所做的事情。$height 很简单,我有高像素数设置要渲染的图像。
此数据是逗号分隔的值列表。我希望这有帮助。看来您断言平均值为 128 是正确的。到目前为止,我一直无法理解您对此的更正。恐怕有点超出我目前的理解范围。
【问题讨论】:
-
+1:我不确定这是否完全符合主题,但我不在乎……这很有趣!
-
你真的需要找到该曲线的方程并应用一个乘法因子;这一切都归结为当你去掉有趣的因素时。如果您不关心小数值(这似乎很可能),您可以完全跳过它,只需手动创建已知值的查找 - 正如 hakre 所建议的那样。
-
确实如此。我确实想知道这是否应该发布在数学网站上。但我敢肯定,我从你们那里得到的回答会比数学家更多地用我的“自己的”语言来表达。 :-)
-
+1 这也是一个写得很好的问题。
-
所需曲线是伽玛校正曲线-
y = pow(x, 1 / gamma)