0

Opencv 2.4.10。
在下面代码的末尾,使用矩阵 Img2 上的 9 个宽磁盘结构元素调用膨胀。最初,Img2 是通过简单的标头副本 (Img2=Img1) 从 Img1 创建的。注意,Img1 是在没有通过 Ranges 从 Img0 复制数据的情况下制作的,因此 Img1 没有 Img0 的第一行和最后 3 行。膨胀的结果不正确。

但是,如果我通过克隆使用 Img2 的完整副本 Img2=Img1.clone(),则膨胀工作正常。

请注意,无论我使用哪种复制方法,在 Img2 上使用 imwrite(未在下面的代码中显示)都是相同的。那么,形态算子不应该也一样吗?

Mat Tmp;
Mat Img1=Img0(Range(3-1, Img0.rows - 3+1),Range::all());

Img1(Range(0,1), Range::all()) = 0;
Img1(Range(Img1.rows-1,Img1.rows), Range::all()) = 0;

// bad
//Mat Img2 = Img1; // header only copy: the dilation results are wrong on the top and bottom 
// good
Mat Img2 = Img1.clone();  // full copy, dilation works right.

Mat Disk4;
// exact replacement for mmatlab strel('disk',4,0), somewhat difference   than opencv's ellipse structuring element.
MakeFilledEllipse( 4, 4, Disk4);  


// If I use Img2 from clone, this is the same as matlab's.  
// If I just do a header copy some areas the top and bottom are different
dilate(Img2, Tmp,Disk4, Point(-1,-1),1,BORDER_CONSTANT, Scalar(0));

编辑- 我随后简化了代码,以便 Img2 替换 img1 并且没有 img1 以便我可以仅使用 1 级 Mat 标头间接重复该问题,但它仍然以相同的方式失败(不正确)。

Mat Tmp;
Mat Img2=Img0(Range(3-1, Img0.rows - 3+1),Range::all());

Img2(Range(0,1), Range::all()) = 0;
Img2(Range(Img2.rows-1,Img2.rows), Range::all()) = 0;

Mat Disk4;
// exact replacement for mmatlab strel('disk',4,0), somewhat difference   than opencv's ellipse structuring element.
MakeFilledEllipse( 4, 4, Disk4);  

// bad result   
dilate(Img2, Tmp,Disk4, Point(-1,-1),1,BORDER_CONSTANT, Scalar(0));
4

1 回答 1

0

Mat在选择自身内部的 ROI 时变得不连续。

我不确定在您的情况下Mat Mat::operator()( Range _rowRange, Range _colRange ) const是否会设置CONTINUOUS_FLAG为 false,但SUBMATRIX_FLAG肯定会设置,这可能会导致不同的操作。

在这里,我猜如果原始图像中有像素围绕您的 ROI,某些部分cv::dilate()(例如边界像素外推方法,或确定像素邻域形状的结构元素)会影响您的输出。

我建议在调用之前使用以下命令重新排序内存cv::dilate()

if (!mat.isContinuous() || mat.isSubmatrix())
{ 
    mat = mat.clone();
}
于 2015-02-19T13:06:42.110 回答