0

我是 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

错误肯定是正确的,正如我type2str在这篇 SO 帖子中使用函数验证的那样: 如何在 OpenCV 中使用 Mat::type() 找出 Mat 对象的类型

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

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

4

1 回答 1

3

此处还提到:Difference Clone CopyToclone() ,在这种情况下, and之间没有区别copyTo()

其实源代码clone()如下:

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

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

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

  • image – 输入 8 位 3 通道图像。
  • 标记——输入/输出标记的 32 位单通道图像(地图)。它应该与图像具有相同的大小。

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

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

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

于 2015-07-02T15:52:38.410 回答