将值映射到像素对 - 如何实现数据结构

Mapping value to pixel pairs - How to implement the data structure

我有一个函数 f(x,y),其中 x 和 y 是像素坐标(就像在 OpenCV cv::Point(i,j) 中一样),它将浮点值映射到每个像素对 (x,y)。我的问题是:表示此映射的正确数据结构是什么?我想要一个类似于具有多种类型的数组的东西,这对于标准数组是不可能的。我想在以下示例中使用它:

mat[cv::Point(i,j)][cv::Point(k,l)] = 5.0f;

非常感谢您的帮助。

您只需要屏幕上 width 像素所在的位置。 这样的功能很容易实现,因为width * height等于像素的数量,你可以写x + y * width来表示地图上的任何像素。

可以使用 std::map:

std::map< Point, std::map< Point, float > > map;
map[Point(0,0)][Point(0,0)] = 5.0f;

但是要这样做,Point 需要 operator<:

struct Point
{
  Point(const size_t _x, const size_t _y) : x(_x), y(_y) {}
  size_t x, y;

  bool operator<(const Point& rhs) const
  {
    // first of all, order regarding x
    if ( x < rhs.x ) return true;
    if ( x > rhs.x ) return false;
    // if x is equal, order regarding y
    if ( y < rhs.y ) return true;
    return false;
  }
};

您当然可以使用 find():

检查地图中是否存在元素 Point(0,0)
if( map.find(Point(0,0)) == map.end() ){ /*Element not found*/ }

如果您可以使用 c++11,std::unorderd_map 也是一个选项,因为您不需要 operator< 作为键 class。


您甚至可以使用 std::pair<Point,Point> 作为地图的键。


另一种选择是使用这样的 4D 阵列:

mat[i][j][k][l] = 5.0f;

正如@Gombat 已经提到的,一个简单的方法是使用 std::map,并使用一个 std::pair<cv::Point, cv::Point> 作为键。

您需要。但是要提供自定义比较器,因为 cv::Point 不提供 operator<

看看这段代码:

#include <opencv2/opencv.hpp>
#include <map>
using namespace cv;
using namespace std;

bool lessPoints(const Point& lhs, const Point& rhs)
{
    return (lhs.x == rhs.x) ? lhs.y < rhs.y : lhs.x < rhs.x;
}

struct lessPairPoints
{
    bool operator()(const pair<Point, Point>& lhs, const pair<Point, Point>& rhs) const
    {
        return (lhs.first == rhs.first) ? lessPoints(lhs.second, rhs.second) : lessPoints(lhs.first, rhs.first);
    }
};

typedef map<pair<Point, Point>, float, lessPairPoints> MapPoints;

int main()
{
    MapPoints map1;

    map1[{Point(0, 0), Point(1, 1)}] = 0.3;
    map1[{Point(1, 2), Point(1, 1)}] = 0.1;

    for (const auto& el : map1)
    {
        cout << el.first.first << ", " << el.first.second << " -> " << el.second << endl;
    }

    cout << map1[{Point(0,0), Point(1,1)}] << endl;

    auto pp = make_pair(Point(1,2), Point(1,1)); 
    cout << map1[pp] << endl;

    return 0;
}