【问题标题】:How to do this the fastest way? Image arrays如何以最快的方式做到这一点?图像数组
【发布时间】:2015-02-19 01:29:42
【问题描述】:

我有一个循环在 C# 中太慢了。我想知道是否有更快的方法来处理这些数组。我目前正在使用 .NET 2.0。我不反对升级这个项目。这是涉及灰度级的理论图像处理概念的一部分。

  • 像素数 (PixCnt = 21144402)
  • g_len = 4625
  • list1d - 具有上述像素数上限的图像的 1 维数组。
  • pg - 灰度强度保持器。

此函数创建这些值的索引。因此 pgidx。

int[] pgidx = new int[PixCnt];
sw = new Stopwatch();
sw.Start();
for (i = 0; i < PixCnt; i++)
{
    j = 0;
    pgidx[i] = 0;
    while (list_1d[i] != pg[j] && j < g_len) j++;
    if (list_id[i] == pg[j])
        pgidx[i] = j
}
sw.stop();
Debug.WriteLine("PixCnt Loop took" + sw.ElapsedMilliseconds + " ms");

【问题讨论】:

  • 多长时间太慢了?
  • 你的变量命名很难理解。

标签: c# arrays performance image-processing optimization


【解决方案1】:

我认为使用字典来存储 pg 数组中的内容会加快速度。 g_len 是 4625 个元素,因此您可能会平均大约 2312 次内部 while 循环迭代。用字典中的单个散列查找替换它应该更快。由于外部循环执行了 2100 万次,因此加速该循环的主体应该会获得丰厚的回报。我猜下面的代码会让你的时间加快 100 到 1000 倍。

var pgDict = new Dictionary<int,int>(g_len);
for (int i = 0; i < g_len; i++) pgDict.Add(pg[i], i);
int[] pgidx = new int[PixCnt];
int value = 0;
for (int i = 0; i < PixCnt; i++) {
    if (pgDict.TryGetValue(list_id[i], out value)) pgidx[i] = value;
 }

请注意,没有必要在未找到匹配项时将 pgidx[i] 设置为零,因为在创建数组时,数组的所有元素都已初始化为零。

如果pg 中的值有可能出现多次,您需要先检查该键是否已添加,如果已添加则跳过将其添加到字典中。这将模仿您当前查找第一个匹配项的行为。为此,将构建字典的行替换为:

for (int i = 0; i < g_len; i++) if (!pgDict.ContainsKey(pg[i])) pgDict.Add(pg[i], i);

【讨论】:

  • 你的概念看起来很棒,但是:我得到 'pgDict.Add(pg[i], i)' -- 已经添加了具有相同键的项目。灰度值不重复。
  • @RobertKoernke - 我认为这可能是一种可能性,并在我的最后一段中提到了这一点。既然您已经说过事实确实如此,我已经编辑了我的答案以显示可以处理该问题的代码。
【解决方案2】:

如果pq 中的像素值范围允许(例如 16 bpp = 65536 个条目),您可以创建一个辅助数组,将所有可能的灰度级映射到pg 中的索引值。通过pg(在初始化为全零之后)单次通过即可填充此数组。

然后使用直接表查找将list_1d 转换为pgidx

如果桌子太大(比图片大),那么按照@hatchet 的回答做。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-09-19
    • 2021-01-10
    • 2011-05-26
    • 1970-01-01
    • 1970-01-01
    • 2021-12-20
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多