C++ OpenCV 中的快速索引

Posted

技术标签:

【中文标题】C++ OpenCV 中的快速索引【英文标题】:Fast indexing in C++ OpenCV 【发布时间】:2018-07-18 11:54:28 【问题描述】:

我对 Python 中的 OpenCV 非常满意。我最近切换到 C++ 版本,我一直遇到cv::Mat 索引的问题,因为我太习惯于numpy 的数组。 特别是,我试图找出是否有更好的方法可以在不遍历数组的情况下对数组的受限区域进行操作。 例如,假设我有一个10x15 酉矩阵,并且我想将除最后一行之外的所有内容都归零(或另一个随机数);在 Python 中,我会这样做:

import numpy as np

a = np.ones([10,15])
a[:-1,:-1] = 0

定义了cv::Mat a = cv::Mat::ones(10, 15, CV_32FC1);,如何在 C++ 中实现这一点?

【问题讨论】:

【参考方案1】:

最好的方法可能是使用感兴趣的区域。 cv mat 可以通过以下方式使用 rect 轻松分区:

using namespace cv;

Mat a = Mat::ones(10, 15, CV_32FC1);
Rect rect(2, 2, 4, 4);
Mat roi = a(rect);

以后你可以用任何你喜欢的方式修改roi,通过:

 roi.copyTo(a(rect));

您可以优雅地在上一行中使用新的Rect,只要它的宽度和高度与原来的Rect 相同。要解决您的具体问题,最简单的方法是创建一个全为零的新矩阵,然后将 copyTo 与该矩阵一起使用。

【讨论】:

这正是我所需要的,谢谢!我只是补充一点,研究一下,可以使用几个 cv::Range 向量(例如,m(cv::Range(i0,i1), cv::Range(j0,j1)) 的技巧等同于 m(cv::Rect(i0,i1,j0-i0,j1-i1)) 非常有帮助。请记住,虽然您发布的原始 numpy 代码是为 numpy 执行此操作的最快方法,但不要期望这是在 c++ 中执行此操作的最快方法。无论哪种情况,它都应该比 numpy 快得多【参考方案2】:

我不知道这是否是最有效的方法,如果不是,那么有人会纠正我。

一种方法是将图像逐行设置为值

for (int i = 0; i < image.rows-1; ++i)

  image.row(i).setTo(Scalar(0,0,0));

或者如果图像数据指针是继续的,那么使用std::fill

if(image.isContinuous())
    std::fill_n(image.data, (image.rows-1) * image.cols * image.elemSize(), 0);

【讨论】:

以上是关于C++ OpenCV 中的快速索引的主要内容,如果未能解决你的问题,请参考以下文章

OpenCV C++:根据存储在 int 向量中的索引为 Mat 类型数据创建列范围

有效的容器,可保持秩序并快速从任何位置删除元素

C++ - 仅使用无符号整数实现快速排序?

慢速CPU的快速索引?

索引概述

从另一个 Dataframe 中的一个 Dataframe 中查找元素并返回其索引的快速方法