【问题标题】:OpenCV clone() and copyTo() methods don't produce Mat of same type as original?OpenCV clone() 和 copyTo() 方法不会产生与原始相同类型的 Mat?
【发布时间】:2015-09-20 06:03:52
【问题描述】:

我是 OpenCV 的新手,并且正在阅读一本书。我正在尝试使用以下内容提取指示组件区域的二进制图像:

cv::Mat result;
result = image.clone();
cv::watershed(image, result);

执行时,会产生以下错误:

segmentation.cpp:159: error: (-215) src.type() == CV_8UC3 && dst.type() == CV_32SC1 
in function watershed

这个错误肯定是正确的,正如我在这篇 SO 帖子中使用 type2str 函数验证的那样:How to find out what type of a Mat object is with Mat::type() in OpenCV

我也尝试使用image.copyTo(result) 而不是clone(),但这会产生相同的错误消息。 我做错了什么,如何复制Mat 以获得相同的类型?

我猜测 hacky 的解决方案是将结果的颜色转换为与图像的颜色匹配,就像这里所做的那样:OpenCV: How to convert CV_8UC1 mat to CV_8UC3 但这似乎是错误的,不是吗?

【问题讨论】:

  • 根本不需要 clone() 或复制图像,这甚至是错误的。只需将结果留空,并确保您的输入 img 是 24bit bgr (CV_8UC3)。

标签: c++ opencv opencv-mat


【解决方案1】:

这里也提到:Difference Clone CopyTo,在这种情况下,clone()copyTo() 之间没有区别。

其实clone()的源码如下:

inline Mat Mat::clone() const
{
    Mat m;
    copyTo(m);
    return m;
}

copyTo 但是可以与掩码结合使用,并且通常将数据复制到另一个矩阵,因此可以用于将子图像绘制到另一个图像中。

关于watershed 的代码,文档指出,

  • 图像 - 输入 8 位 3 通道图像。
  • markers – 输入/输出 32 位单通道标记图像(地图)。它应该与图片大小相同。

所以image(你的image)和markers(你的result)不应该是一样的。

在将图像传递给函数之前,您必须在图像标记中用正 (>0) 索引粗略勾勒出所需区域。因此,每个区域都表示为一个或多个具有像素值 1、2、3 等的连通分量。可以使用 findContours() 和 drawContours() 从二进制掩码中检索此类标记(请参阅 watershed.cpp 演示)。标记是未来图像区域的“种子”。标记中的所有其他像素,其与轮廓区域的关系未知,应由算法定义,应设置为 0。在函数输出中,标记中的每个像素都设置为“种子”组件的值,或者在区域之间的边界处设置为 -1。

函数的可视化演示和使用示例可以在OpenCV示例目录中找到(参见watershed.cpp演示)。

【讨论】:

  • 我明白你的意思,但我的问题的另一部分是为什么在 .clone 或 .copyTo 方法之后结果和图像不匹配?
  • 没有区别。除非您在 copyTo 中指定 roi,但这是另一回事。
  • 用 copyTo 和 clone 的详细信息更新答案
猜你喜欢
  • 1970-01-01
  • 2021-08-11
  • 1970-01-01
  • 2016-12-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-03-07
  • 1970-01-01
相关资源
最近更新 更多