【问题标题】:Mat cells set to NULL in OpenCV?在 OpenCV 中将 Mat 单元格设置为 NULL?
【发布时间】:2017-03-04 18:05:27
【问题描述】:

快速总结:

我创建了一个 cv::Mat

cv::Mat m = cv::Mat::zeros(MAP_HEIGHT, MAP_WIDTH, CV_8UC1)

之后我的方法是查看我在多边形列表中是否有任何多边形,如果有,请填写它们,最后我将 m 分配给我的公共 cv::Mat 映射(在头文件中定义)。 发生的事情基本上是:

cv::Mat m = cv::Mat::zeros(MAP_HEIGHT, MAP_WIDTH, CV_8UC1);
// possibly fill polygons with 1's. Nothing happens if there are no polygons
map = m;

我的程序的逻辑是,如果 0 占据单元格,则允许位置 x,y。所以没有多边形 => 所有地图都应该是“合法的”。

我已经定义了这个方法来检查是否允许给定的 x-y 坐标。

bool Map::isAllowed(bool res, int x, int y) {
    unsigned char allowed = 0;
    res = (map.ptr<unsigned char>(y)[x] == allowed);
}

现在谜团开始了。

cout << cv::countNonZero(map) << endl; // prints 0, meaning all cells are 0
for(int i = 0; i < MAP_HEIGHT; i++) {
    unsigned char* c = map.ptr<unsigned char>(i);
    for(int j = 0; j < MAP_WIDTH; j++) {
        cout << c[j] << endl;
    }
} // will print nothing, only outputs empty lines, followed by a newline.

如果我打印 (c[j] == NULL),它会打印 1。 如果我打印整个 Mat,我只会看到 0 在我的屏幕上闪烁,所以它们很明显就在那里。

为什么 isAllowed(bool, x, y) 为 (0,0) 返回 false,而那里显然是 0?

如果需要更多信息,请告诉我,谢谢!

【问题讨论】:

  • 使用cout &lt;&lt; int(c[j]) &lt;&lt; endl;。您正在打印 ASCII 字符,而不是值。 (NULL 就是 0)。而map.ptr&lt;unsigned char&gt;(y)[x] 可以简单地重写为map.at&lt;uchar&gt;(y,x),或者如果你使用Mat1bmap(y,x)
  • @Miki 这实际上打印了 0,谢谢。后续问题;为什么如果我执行 (unsigned char)c[j] 会得到与以前相同的结果,但如果执行 int(c[j]) 会得到实际的 0?我有一个错误,我从 Mat 中收集和读取 int,但我想要无符号字符。当垫子填充为 1 时,这将为我提供以下 4 个单元格内容的数值。
  • 如果您打印 uchar 数据,您将获得 ASCII 值。要获得实际值,您可以转换为 int。由于 uchar 是 1 个字节,int 是 4 个字节,如果你在 uchar* 中分配一个 int 值,你实际上是在写 4 uchars

标签: c++ opencv null mat


【解决方案1】:

由于您的数据类型是 uchar(又名 unsigned char),因此您正在打印 ASCII 值。使用

cout << int(c[j]) << endl;

打印实际值。


也可以将map.ptr&lt;unsigned char&gt;(y)[x] 重写为map.at&lt;uchar&gt;(y,x),或者如果您使用Mat1bmap(y,x)

【讨论】:

  • isAllowed(res, 0, 0) 仍将返回 false。我相应地更改了方法,在比较之前转换为 int 。无符号字符* c = map.ptr(y); int cellval = int(p[x]); res = cellval == int(0);
  • 您需要强制转换为 int 才能打印出该值,而不是在您的处理中。
【解决方案2】:

问题已经解决了,以下是我的错误供以后参考:

1:打印时,@Miki 指出打印的是无符号字符 -> ASCII 值,而不是数字表示。

2:在isAllowedPosition(bool res, int x, int y)中,res有一个原始类型。也就是这被推送到堆栈上,而不是对内存位置的引用。写入时,我会写入本地副本,而不是作为参数传入的副本。

两种可能的修复方法,要么传入指向内存位置的指针并写入该位置,要么直接返回结果。

【讨论】:

  • 或者只是“return res;”
猜你喜欢
  • 1970-01-01
  • 2013-05-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-06-27
  • 2011-09-12
  • 2021-11-16
  • 2012-10-19
相关资源
最近更新 更多