OpenCV C# 像 C++ 一样迭代 Mat 对象

Posted

技术标签:

【中文标题】OpenCV C# 像 C++ 一样迭代 Mat 对象【英文标题】:OpenCV C# iterate Mat object like C++ 【发布时间】:2019-08-02 09:23:24 【问题描述】:

我正在尝试学习用 C++ 编写的 OpenCV 教程,但我需要用 C# 编写它。到目前为止,这工作得很好。 因为我不是 C++ 开发人员,也不是。熟悉这门语言的我现在有点挣扎,我不确定我所做的是否等同于 C++ 版本。

这是 C++ 中的代码

vector<Point> pointsOfInterest;
Mat_<uchar>::iterator itMask = mask.begin<uchar>();
Mat_<uchar>::iterator end = mask.end<uchar>();
for( ; itMask!=end; ++itMask)
    if(*itMask==255)
        pointsOfInterest.push_back(itMask.pos());

我在这里读到的是一个循环,它遍历整个 Mat 并检查位置的值是否为 255,如果是,它将点添加到 pointsOfInterest 列表的末尾。

所以我猜这意味着 Mat 中的每个 x,y 像素都会检查值。我在 C# 中的等效项如下所示:

List<Point> pointsOfInterest = new List<Point>();
for(int x = 0;x<mask.Cols;x++)

    for(int y=0;y<mask.Rows; y++)
    
        if (mask.At<int>(x, y) == 255)
            pointsOfInterest.Add(new Point(x, y));
    

但我得到的结果并不像预期的那样,这就是为什么我想知道这部分是否真的正确?有时 mask.At 也会抛出一个 NullPointer,这很奇怪。我也想知道 C++ 只是迭代一个一维数组(我认为至少)同时 C# 需要二维。

有人可以确认它是相同的还是有人知道哪里出了问题并且需要调整?

【问题讨论】:

mask 是可枚举的吗?在我的脑海中,尝试用 foreach 替换两个 for 循环(在非常高级的意义上,类似的事情也在 C++ 中发生)。它甚至可能比调用.At&lt;int&gt;(x, y) 更有效率。唯一的问题是如何获取位置,但可能是由 C# 中的枚举器类型处理的。 感谢您的快速输入 :) 掩码属于 Mat 类型,不幸的是,Mat 不可枚举:/ 顺便说一句,你在用什么?恩古简历? mask 的类型是什么?有在线文档吗?如果您提供教程的链接,它也可以帮助我们。编辑:刚刚看到你的评论 - 在那之前写的。 掩码是 Mat 类型。该教程我无法发布,因为实际上它是一本书:D 我正在使用 Unity 和这个资产 assetstore.unity.com/packages/tools/integration/… 用于 OpenCV 好的,根据那个页面,这个统一资产所基于的 OpenCV 库是 this,这是 Mat class 的来源。这是docs,但它们不是很有帮助。 【参考方案1】:

我还发现,更改 img.At(y,x) 的 x 和 y 将解决异常,您将获得列表中的点。

【讨论】:

以上是关于OpenCV C# 像 C++ 一样迭代 Mat 对象的主要内容,如果未能解决你的问题,请参考以下文章

C++的opencv里怎么读取Mat图像中特定坐标的灰度值?

如何使用 C# 脚本在 Unity 中将 OpenCV Mat 转换为 Texture2D?

在 OpenCV (C++) 中打印多维 Mat

OpenCV学习C++接口 Mat像素遍历详解

OpenCV C++ Mat == 运算符

C++ OpenCV Mat 像素值和 OpenCV 错误