65.9K
CodeProject 正在变化。 阅读更多。
Home

用于采样数据流的输入输出迭代器

starIconstarIconstarIcon
emptyStarIcon
starIcon
emptyStarIcon

3.75/5 (4投票s)

2003年11月4日

2分钟阅读

viewsIcon

47748

downloadIcon

804

这些迭代器提供了一种简单的方法来采样或拉伸固定大小的数据集以适应更大或更小的容器。

引言

我正在开发一个使用 Direct3D 显示 3D 路径的应用程序,遇到了视频卡在路径元素数量上的限制。为了解决这个问题,我编写了一些简单的代码来采样我生成的数据,而不仅仅是在固定点处截断数据。虽然我最初是为这个特殊情况设计的,但这个问题是一个普遍存在的问题,例如在拉伸或缩小数据(如图像)或更改音频文件的采样率时。

我搜索了一些可以完成这项任务的代码,最接近的是为 boost 过滤器迭代器编写自定义谓词。在编写谓词时,我意识到有一个更通用的解决方案,不仅可以采样数据集,还可以拉伸它。

为了提供最灵活和易于使用的接口,我提供了三种使用采样算法的方法。通过输入迭代器、输出迭代器或可以由 boost 过滤器迭代器或 STL remove_if 算法使用的谓词。

使用代码

使用迭代器相对简单。遵循 STL 约定,我提供了成对的模板函数,以便轻松创建输入和输出迭代器形式。这是一个简单的示例,展示了输入和输出形式的使用。

  std::vector list;
  for(int i=0; i<7; ++i)
    list.push_back(i);

  std::cout << "Original sequence:" << std::endl;
  std::copy(list.begin(), list.end(), std::ostream_iterator(std::cout, " "));
  std::cout << std::endl;

  std::cout << "Input sampled/stretched at various intervals:" << std::endl;
  for(size_t dest_size = 1; dest_size<=list.size()*2; ++dest_size)
  {
    std::copy(sample::sample(list.begin(), dest_size, list.size()), 
         sample::sample(list.end(), dest_size, list.size()), 
         std::ostream_iterator(std::cout, " "));
    std::cout << std::endl;
  };

  std::cout << "Output sampled/stretched at various intervals:" << std::endl;
  for(size_t dest_size = 1; dest_size<=list.size()*2; ++dest_size)
  {
    std::copy(list.begin(), list.end(), sample::sample_output(
        std::ostream_iterator(std::cout, " "), dest_size, list.size()));
    std::cout << std::endl;
  };

这些对象的主要限制是,您必须知道输入和输出数据集的大小。此外,使用了一种简单的采样方法,它只考虑元素在数据集中的位置。它不会查看采样点的质量来决定是否丢弃。例如,采样 3D 曲线的最佳解决方案是在决定丢弃数据点时考虑每个点的曲率。

关注点

我怀疑将实际基础迭代器对象的所有权从函数对象移到包装迭代器对象中,可以提供更大的灵活性和易用性。我现在正在开发一些更高级的采样函数对象,它们将使用平均/线性插值以及样条插值,我认为拥有迭代器会简化这些对象,因为它们将更容易让算法读取/写入插值数据,而无需过度访问迭代器类的内部对象。我希望在不久的将来发布更新的函数对象,并包含任何必要的更新,以使这些迭代器能够正常工作。

© . All rights reserved.