Morphological operations (erode / dilate) have problems when number of iterations > 1 on a full kernel (Bug #2348)
Description
There is a problem in
opencv\modules\imgproc\src\morph.cpp
in
static void morphOp( int op, InputArray _src, OutputArray _dst,
InputArray _kernel,
Point anchor, int iterations,
int borderType, const Scalar& borderValue )
There is an optimization: instead of iterating iter times, a larger kernel is constructed. The intention is good, but the implementation is not.
The correct kernel size should be:
kernel = getStructuringElement(MORPH_RECT,
Size(ksize.width + (iterations-1)*(ksize.width-1),
ksize.height + (iterations-1)*(ksize.height-1)),
anchor);
The snippet of code should be:
@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;
}@
In order to test, one should expect that on a test image:
cv::dilate(Input, Output1, cv::Mat::ones(3,3,CV_8U), cv::Point(-1,-1), 2);
cv::erode(Input, Output1, cv::Mat::ones(3,3,CV_8U), cv::Point(-1,-1), 2);
and
cv::dilate(Input, Output2, cv::Mat::ones(3,3,CV_8U), cv::Point(-1,-1), 1);
cv::dilate(Output2, Output2, cv::Mat::ones(3,3,CV_8U), cv::Point(-1,-1), 1);
cv::erode(Output2, Output2, cv::Mat::ones(3,3,CV_8U), cv::Point(-1,-1), 1);
cv::erode(Output2, Output2, cv::Mat::ones(3,3,CV_8U), cv::Point(-1,-1), 1);
should produce the same results, and they do not.
See the attached images.
Associated revisions
fixed iterations>1 case in morphological operations (bug #2348; thanks to Andrei Zaharescu for the fix)
Merge pull request #2348 from ilya-lavrenov:typo
History
Updated by Vadim Pisarevsky over 12 years ago
thanks! the bug was fixed in 9956c4
- Assignee set to Vadim Pisarevsky
- Category set to imgproc, video
- Target version set to 2.4.3
- Status changed from Open to Done