简述
在进行腐蚀或膨胀操作时,碰到了这样一个问题:“OpenCV Error: Assertion failed (anchor.inside(Rect(0, 0, ksize.width, ksize.height))) in cv::normalizeAnchor, file C:/buildslave64/win64_amdocl/2_4_PackSlave-win32-vc10-shared/opencv/modules/imgproc/src/precomp.hpp, line 88” 。
问题分析
仔细检测代码,发现在使用erode() 或 dilate()函数时,核参数输入有误。我的调用代码如下:
Mat element = getStructuringElement(MORPH_RECT, Size(2, 2));
erode(src, dst, element);
大家能发现问题是什么吗?核参数为2,这个错误的。细心的朋友应该会发现腐蚀和膨胀函数介绍时,默认核大小为3*3,说明核参数不可以小于3。
morphOp 数学形态学滤波函数, 腐蚀和膨胀就是通过这个函数得到的,我们来看下这个函数的源码:
//_kernel : 形态学滤波的核
//anchor: 锚点再滤波核的位置
//iterations: 迭代次数
static void morphOp( int op, InputArray _src, OutputArray _dst,
InputArray _kernel,
Point anchor, int iterations,
int borderType, const Scalar& borderValue )
{
Mat src = _src.getMat(), kernel = _kernel.getMat();
Size ksize = kernel.data ? kernel.size() : Size(3,3);
anchor = normalizeAnchor(anchor, ksize);
CV_Assert( anchor.inside(Rect(0, 0, ksize.width, ksize.height)) );
_dst.create( src.size(), src.type() );
Mat dst = _dst.getMat();
if( iterations == 0 || kernel.rows*kernel.cols == 1 )
{
src.copyTo(dst);
return;
}
if( !kernel.data )
{
kernel = getStructuringElement(MORPH_RECT, Size(1+iterations*2,1+iterations*2));
anchor = Point(iterations, iterations);
iterations = 1;
}
else if( iterations > 1 && countNonZero(kernel) == kernel.rows*kernel.cols )
{
anchor = Point(anchor.x*iterations, anchor.y*iterations);
kernel = getStructuringElement(MORPH_RECT,
Size(ksize.width + (iterations-1)*(ksize.width-1),
ksize.height + (iterations-1)*(ksize.height-1)),
anchor);
iterations = 1;
}
int nStripes = 1;
#if defined HAVE_TBB && defined HAVE_TEGRA_OPTIMIZATION //这里是TBB指令集操作, 如果你的库没有使用tbb 则这句话不会执行
if (src.data != dst.data && iterations == 1 && //NOTE: threads are not used for inplace processing
(borderType & BORDER_ISOLATED) == 0 && //TODO: check border types
src.rows >= 64 ) //NOTE: just heuristics
nStripes = 4;
#endif
parallel_for(BlockedRange(0, nStripes),
MorphologyRunner(src, dst, nStripes, iterations, op, kernel, anchor, borderType, borderType, borderValue));
//Ptr<FilterEngine> f = createMorphologyFilter(op, src.type(),
// kernel, anchor, borderType, borderType, borderValue );
//f->apply( src, dst );
//for( int i = 1; i < iterations; i++ )
// f->apply( dst, dst );
}