如何通过另一个具有位置(索引)的垫子访问opencv中的矩阵数据

Posted

技术标签:

【中文标题】如何通过另一个具有位置(索引)的垫子访问opencv中的矩阵数据【英文标题】:How to access matrix data in opencv by another mat with locations (indexing) 【发布时间】:2018-03-11 11:40:31 【问题描述】:

假设我有一个名为 B 的索引(位置)Mat,我们可以说这个 Mat 的维度为 1 x 100 并且我们假设有另一个 Mat,称为 A,充满了与 B 相同维度的数据。 现在,我将使用 B 访问 A 的数据。通常我会创建一个 for 循环,并且我会获取 B 的每个元素,A 的正确元素。对于最挑剔的网站,这是我的代码会写:

for(int i=0; i < B.cols; i++)
    int index = B.at<int>(0, i);
    std::cout<<A.at<int>(0, index)<<std:endl;

好的,现在我已经向您展示了我可以做什么,请问您是否有一种方法可以更智能、更快速地访问矩阵 A,始终使用 B 索引。由于numpy.take() 函数,有人可以在 python 中执行此操作。

【问题讨论】:

【参考方案1】:

此操作称为remapping。在 OpenCV 中,您可以为此目的使用函数 cv::remap。

下面我将介绍重映射算法如何工作的非常基本的示例;请注意,在此示例中我不处理边界条件,但 cv::remap 处理 - 它允许您使用镜像、钳制等来指定如果索引超过图像尺寸会发生什么。我也没有展示插值是如何完成的;检查我上面链接到的cv::remap 文档。

如果您要使用重映射,您可能必须将索引转换为浮点数;如果您的图像是一维的,您还必须引入另一个索引数组,该数组应该是微不足道的(都等于 0)。如果这开始代表性能问题,我建议您自己实现一维重映射等效项。当然,在优化之前先进行基准测试。

有关所有详细信息,请查看文档,其中涵盖了使用 te 算法所需了解的所有内容。

cv::Mat<float> remap_example(cv::Mat<float> image, 
                             cv::Mat<float> positions_x, 
                             cv::Mat<float> positions_y)

   // sizes of positions arrays must be the same
   int size_x = positions_x.cols;
   int size_y = positions_x.rows;
   auto out = cv::Mat<float>(size_y, size_x);

   for(int y = 0; y < size_y; ++y)
     for(int x = 0; x < size_x; ++x)
     
       float ps_x = positions_x(x, y);
       float ps_y = positions_y(x, y);

       // use interpolation to determine intensity at image(ps_x, ps_y),
       // at this point also handle border conditions 
       // float interpolated = bilinear_interpolation(image, ps_x, ps_y);

       out(x, y) = interpolated;
      

return out;

【讨论】:

【参考方案2】:

一种快速的方法是对 A(数据)和 B(索引)都使用指针。

const int* pA = A.ptr<int>(0);
const int* pIndexB = B.ptr<int>(0);
int sum = 0;
for(int i = 0; i < Bi.cols; ++i)

    sum += pA[*pIndexB++];

注意:注意像素类型,在这种情况下(如您在代码中所写)是 int!

注意2:对每个点访问使用cout会使优化无用!

注意3:在本文中 Satya 比较了四种像素访问方法,最快的似乎是“foreach”:https://www.learnopencv.com/parallel-pixel-access-in-opencv-using-foreach/

【讨论】:

以上是关于如何通过另一个具有位置(索引)的垫子访问opencv中的矩阵数据的主要内容,如果未能解决你的问题,请参考以下文章

数据结构:使用面向对象模拟数组

如何使用具有相同索引的另一个数据框来索引数据框的值?

如何使用另一个日期时间索引获取具有日期时间索引的 Pandas 数据框中的行?

Powershell 与 Access 2007 的交互,如何将报告另存为 PDF?

垫子类型转换和访问单个像素的问题

通过索引对类模板成员的编译时访问