地图 - 寻找最接近的值?

发布于 2024-11-24 04:20:56 字数 636 浏览 6 评论 0原文

我正在尝试在 QMap 中找到最接近的 RGB 值(我知道它可能应该是 HSV,但这不是问题)。这是我到目前为止得到的:

        it = images_map.find(current_rgb);

        if(it != images_map.begin()){
            mi = images_map.lowerBound(current_rgb).value();
        }
        else{
            mi = images_map.upperBound(current_rgb).value();
        }

我的地图看起来像这样有索引:

images_map[ 4283914078 ] 
images_map[ 4284046165 ] 
images_map[ 4284902241 ] 
images_map[ 4289239953 ] 
images_map[ 4282200377 ] 
images_map[ 4289440688 ] 

当我的 current_rgb 是例如 4285046165 时,这是可以的,但如果有一些值大于最大索引,程序崩溃。我做错了什么?

I am trying find nearest RGB value in QMap (I know it probably should be HSV, but that is not the problem). Here is what I got so far:

        it = images_map.find(current_rgb);

        if(it != images_map.begin()){
            mi = images_map.lowerBound(current_rgb).value();
        }
        else{
            mi = images_map.upperBound(current_rgb).value();
        }

My map looks like this has that indexes:

images_map[ 4283914078 ] 
images_map[ 4284046165 ] 
images_map[ 4284902241 ] 
images_map[ 4289239953 ] 
images_map[ 4282200377 ] 
images_map[ 4289440688 ] 

When my current_rgb is for example 4285046165 it is OK, but if there is some value greater than greatest index, program crashes. What am I doing wrong?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

失眠症患者 2024-12-01 04:20:56

可能是因为 .value() 尝试取消引用不存在的项目?

这看起来像您自己的自定义地图实现(或包装器),但您的逻辑似乎不正确

  1. 您每次都会调用 lowerBound - 除非您正在查找的项目是地图中的第一个项目
  2. 如果是地图上的第一个,你再搜索一次???
  3. 如果不是,您再次搜索(如果已经找到,则再次重复操作),否则如果没有找到,则查找最近的(这是可以的),但是您是否处理没有的情况(即在 lowerBound< /代码>)?

逻辑应该是这样的:

it = images_map.find(current_rgb);

if(it == images_map.end())
{
  it = images_map.lowerBound(current_rgb);
  if (it == images_map.begin())
  {
    it = images_map.upperBound(current_rgb);
    if (it == images_map.end()) 
      // throw error
  }
  // now you know you have a valid iterator - de-reference
  mi = *it.value();
}

Possibly because .value() tries to de-reference a non-existing item?

This looks like your own custom map implementation (or wrapper), but your logic appears to be incorrect

  1. You call lowerBound every time - except if the item you are looking for is the first in the map
  2. If it is the first in the map, you do a search again???
  3. If it's not you search again (which if already found is repeating the operation again), else if not found, looks for nearest (which is okay), however do you handle the case where there is none (i.e. in lowerBound)?

The logic should be something like:

it = images_map.find(current_rgb);

if(it == images_map.end())
{
  it = images_map.lowerBound(current_rgb);
  if (it == images_map.begin())
  {
    it = images_map.upperBound(current_rgb);
    if (it == images_map.end()) 
      // throw error
  }
  // now you know you have a valid iterator - de-reference
  mi = *it.value();
}
雪落纷纷 2024-12-01 04:20:56

调用

images_map.upperBound(current_rgb) 

可能会返回

images_map.end()

在这种情况下,您不应调用 value()

Call

images_map.upperBound(current_rgb) 

May return

images_map.end()

In that case you should not call value().

耳钉梦 2024-12-01 04:20:56

您可以通过添加标记值 0x0000000xFFFFFF(一次)来解决迭代器超出范围的问题。这样,您始终拥有有效的下限和上限。当然,这可能会影响算法的结果。例如,如果您的“最小”真实颜色是纯蓝色 (0x0000FF),那么深蓝色 (0x00007F) 现在会发现黑色,而不是纯蓝色。当然,通过两次比较就可以轻松解决这个问题。

哨兵就位后,调用QMap::lower_bound。您需要检查是否确实找到了精确匹配:如果 *lower_bound 是您想要的值,则返回它。否则,lower_bound 指向比您的输入大的第一个元素。因此,--lowerbound 指向小于您输入的最后一个元素。检查两者中哪一个更接近。

请注意,lower_bound 可以指向 begin 的唯一方法是当您的输入恰好是 0x000000(哨兵)时,在这种情况下您将不会到达--lower_bound。那里没有范围错误。按照相同的逻辑,结束标记 0xFFFFFF 意味着您始终会找到 lower_bound

You can solve the iterator out of range problem by adding sentinel values 0x000000 and 0xFFFFFF (once). That way, you always have a valid lower- and upperbound. Of course, this may affect the outcome of your algorithm. E.g. if your "smallest" real color was pure blue (0x0000FF), then dark blue (0x00007F) will now find black, not pure blue. This is easily fixed by two comparisons, of course.

With the sentinels in place, call QMap::lower_bound. You need to check whether you've actually found a precise match: if *lower_bound is the value you want, return it. Else, lower_bound points to the first element that's bigger than your input. Therefore, --lowerbound points to the last element that's smaller than your input. Check which of the two is closer.

Note that the only way lower_bound can point to begin is when your input is precisely 0x000000 (the sentinel), in which case you won't get to --lower_bound. No range error there. By the same logic, the end sentinel 0xFFFFFF means you'll always find an lower_bound.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文