【问题标题】:How to improve the efficiency of QVector lookup?QVector查找效率如何提高?
【发布时间】:2021-12-11 16:54:16
【问题描述】:

由于某种原因,我需要多次遍历一张图像,我需要知道我处理了哪些像素点。

所以我使用 QVector 来存储我每次处理的像素点的位置,以便我可以使用它来确定下一次迭代的时间。

示例如下。

QVector<int> passed;
for(int n = 0; n < 10; n++) { // Multiple traversals
    for(int y = 0; y < height; y++) {
        for(int x = 0; x < width; x++) {
            if(......) { // Meeting certain conditions
                if(!passed.contains(y*width+x)) {
                    // do something
                    passed.append(y*width+x);
                }
            }
        }
    }
}

我花了很多时间处理passed.contains()这一步!

你知道如何优化搜索速度吗?

或者有没有更好的方法让我更容易确定已处理的某些像素?

【问题讨论】:

  • (无序)集合比线性搜索有更好的查找。所以在 QT 中,它将是 QSet.
  • 任何类型的无序集合、散列或集合对于普通的旧布尔数组来说都不是最佳的(在速度和内存使用方面)。查看我的解决方案。
  • 您已将此问题标记为OpenCV,因此您应该已经了解 cv::Mat -- 使用掩码图像进行查找,输入 boolean 或 uint8。将“像素”设置为 0 或 1。查找将是 O(1)。与 V.K. 的答案相同的想法,但隐藏了索引计算,因为它是图像,而不是平面数组。 -- 存储坐标是不合理的。

标签: c++ qt opencv vector


【解决方案1】:

使用这个:

QVector<bool> passed(height * width, false);

for(int n = 0; n < 10; n++) { // Multiple traversals
    for(int y = 0; y < height; y++) {
        for(int x = 0; x < width; x++) {
            if(......) { // Meeting certain conditions
                int pos = y*width+x;
                if(!passed.at(pos)) {
                    // do something
                    passed[pos] = true;
                }
            }
        }
    }
}

或者也许你可以通过重新排序内部条件来更快。如果评估if(......) 不是微不足道的,它可能会明显更快。但您必须确保此更改不会影响您的算法。

QVector<bool> passed(height * width, false);

for(int n = 0; n < 10; n++) { // Multiple traversals
    for(int y = 0; y < height; y++) {
        for(int x = 0; x < width; x++) {
            int pos = y*width+x;
            if(!passed.at(pos)) {
                if(......) { // Meeting certain conditions
                    // do something
                    passed[pos] = true;
                }
            }
        }
    }
}

【讨论】:

  • 非常感谢,我之前使用 contains 的想法太愚蠢了。
【解决方案2】:

QVector 中的元素是否必须按顺序存储?如果没有,请尝试 QSet 或 std::unordered_set。哈希在搜索时效果很好。

如果你必须按顺序存储这些索引,有办法:

  1. 用列表替换vector,比如std::list,追加时速度更快
  2. 继续使用 QVector 但调用 reserve 以避免在追加时进行无用的复制
  3. 一种按顺序存储的新方法:创建一个与图像大小相同的 qvector,向量中的每个元素记录该元素的顺序。例如,第 4 个元素是 32 表示第 4 个像素是第 33 个访问像素。

【讨论】:

  • 我试过了,使用 QSet 更快,感谢您的回答。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-04-27
  • 2013-07-03
  • 2021-09-22
  • 2017-02-27
  • 2013-03-11
  • 2011-02-21
  • 2016-12-18
相关资源
最近更新 更多