带有大量样本的绘图信号 [英] Drawing signal with a lot of samples

查看:86
本文介绍了带有大量样本的绘图信号的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要显示一组信号。每个信号由数百万个样本定义。仅处理样本的集合(根据位图大小将样本转换为点)会花费大量时间(尤其是在滚动过程中)。

I need to display a set of signals. Each signal is defined by millions of samples. Just processing the collection (for converting samples to points according to bitmap size) of samples takes a significant amount of time (especially during scrolling).

因此,我实现了某种下采样。我只是跳过了一些要点:根据信号特性,每隔2、3、50分。

So I implemented some kind of downsampling. I just skip some points: take every 2nd, every 3rd, every 50th point depending on signal characteristics. It increases speed very much but significantly distorts signal form.

有没有更聪明的方法?

推荐答案

在最近的应用程序中,我们遇到了类似的问题。当缩小视图时,我们的可视化效果(简单的折线图)变得过于混乱,无法看到整个数据范围(大约7天的采样,每6秒或多或少每采样一次采样一次),因此降采样实际上是解决之道。如果我们不这样做,则缩小将没有太大的意义,因为您看到的只是在屏幕上抹出的一整行线条。

We've had a similar issue in a recent application. Our visualization (a simple line graph) became too cluttered when zoomed out to see the full extent of the data (about 7 days of samples with a sample taken every 6 seconds more or less), so down-sampling was actually the way to go. If we didn't do that, zooming out wouldn't have much meaning, as all you would see was just a big blob of lines smeared out over the screen.

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

It all depends on how you are going to implement the down-sampling. There's two (simple) approaches: down-sample at the moment you get your sample or down-sample at display time. What really gives a huge performance boost in both of these cases is the proper selection of your data-sources.

假设您有700万个样本,并且您的查看窗口仅对最近一百万个积分感兴趣。如果您的实现依赖于IEnumerable,则意味着IEnumerable必须在实际启动前移动MoveNext 600万次。但是,如果您使用的是针对随机读取进行了优化的东西(想到一个列表),则可以为此实现自己的枚举器,大致是这样的:

Let's say you have 7 million samples, and your viewing window is just interested in the last million points. If your implementation depends on an IEnumerable, this means that the IEnumerable will have to MoveNext 6 million times before actually starting. However, if you're using something which is optimized for random reads (a List comes to mind), you can implement your own enumerator for that, more or less like this:

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循环中执行您想要的任何操作(使用基于周围样本的算法进行平均吗?)。但是,这种方法通常可以消除信号中的任何尖峰,因此请警惕。

Obviously this is a very naive implementation, but you can do whatever you want within the for-loop (use an algorithm based on the surrounding samples to average?). However, this approach will make usually smooth out any extreme spikes in your signal, so be wary of that.

另一种方法是为数据集创建一些通用版本不同的范围,每当您收到新信号时都会自动更新。您通常不需要更新完整的数据集;仅更新集合的末尾可能就足够了。这使您可以对数据进行更高级的处理,但是会占用更多的内存。您必须在应用程序中缓存不同的细节层。

Another approach would be to create some generalized versions of your dataset for different ranges, which update itself whenever you receive a new signal. You usually don't need to update the complete dataset; just updating the end of your set is probably good enough. This allows you do do a bit more advanced processing of your data, but it will cost more memory. You will have to cache the distinct 'layers' of detail in your application.

但是,阅读您的(简短的)解释后,我认为显示时间优化可能会很好足够。如果进行概括,您总是会在信号中产生失真。您总是会丢失数据。取决于您选择的算法来确定这种失真的发生方式以及这种失真的程度。

However, reading your (short) explanation, I think a display-time optimization might be good enough. You will always get a distortion in your signal if you generalize. You always lose data. It's up to the algorithm you choose on how this distortion will occur, and how noticeable it will be.

这篇关于带有大量样本的绘图信号的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆