绘制信号有很多样本

时间:2012-04-20 11:52:45

标签: c# .net drawing

我需要显示一组信号。每个信号由数百万个样本定义。只处理样本的集合(用于根据位图大小将样本转换为点)需要花费大量时间(特别是在滚动期间)。

所以我实施了某种下采样。我只是跳过一些要点:根据信号特征,每隔2个,每隔3个,每50个点取一个点。它会极大地提高速度,但会严重扭曲信号形式。

有更聪明的方法吗?

2 个答案:

答案 0 :(得分:2)

我们在最近的一个应用程序中遇到了类似的问题。当缩小以查看数据的完整范围时,我们的可视化(简单的线图)变得太杂乱(大约7天的样本每隔6秒或多或少地采样一次),因此下采样实际上是要走的路。如果我们不这样做,缩小就没有多大意义,因为所有你会看到的只是在屏幕上抹去一大堆线条。

这完全取决于您将如何实施下采样。有两种(简单)方法:在您获取样品时下采样或在显示时下采样。 在这两种情况下,真正提高性能的是正确选择数据源。

假设您有700万个样本,您的查看窗口只对最后的百万分感兴趣。如果你的实现依赖于IEnumerable,这意味着IEnumerable在实际启动之前必须有600万次MoveNext。但是,如果您正在使用针对随机读取进行优化的内容(我会想到一个List),您可以为此实现自己的枚举器,或多或少是这样的:

public IEnumerator<T> GetEnumerator(int start, int count, int skip)
{
    // assume we have a field in the class which contains the data as a List<T>, named _data
    for(int i = start;i<count && i < _data.Count;i+=skip)
    {
        yield return _data[i];
    }
}

显然这是一个非常天真的实现,但你可以在for循环中做任何你想做的事情(使用基于周围样本的算法来平均?)。但是,这种方法通常可以平滑信号中的任何极端尖峰,因此要小心。

另一种方法是为不同的范围创建数据集的某些通用版本,每当您收到新信号时它们都会更新。您通常不需要更新完整的数据集;只是更新你的集合的结尾可能已经足够了。这允许您对数据进行更高级的处理,但会花费更多内存。您必须在应用程序中缓存不同的“层”细节。

然而,阅读你的(简短)解释,我认为显示时优化可能已经足够了。如果你推广的话,你的信号总会出现失真。你总是丢失数据。这取决于你选择的算法如何发生这种失真,以及它会有多明显。

答案 1 :(得分:1)

您需要更好的采样算法,也可以使用c#的并行处理功能。请参阅Task Parallel Library