Opencv 2.4.10.
В конце приведенного ниже кода расширение вызывается с помощью структурирующего дискового элемента шириной 9 на матрице Img2. Первоначально Img2 был создан из Img1 с помощью простой копии заголовка (Img2 = Img1). Обратите внимание, что Img1 был создан без копирования данных из Img0 через диапазоны, так что Img1 не имеет первых и последних 3 строк Img0. Результат расширения был неверным.
Однако, если я использовал полную копию Img2 через клон Img2 = Img1.clone (), расширение работало правильно.
Обратите внимание, что использование imwrite, не показанного в приведенном ниже коде, на Img2 было одинаковым независимо от того, какой метод копирования я использовал. Так не должны ли морфологические операторы работать одинаково?
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));
Mat
стал непостоянным в результате выбора ROI внутри себя.
Я не уверен, что в вашем случае Mat Mat::operator()( Range _rowRange, Range _colRange ) const
установит CONTINUOUS_FLAG
ложно, но SUBMATRIX_FLAG
будет установлено обязательно, что может привести к разной работе.
Здесь, я думаю, некоторые части cv::dilate()
(например, метод экстраполяции граничного пикселя или структурирующий элемент, определяющий форму окрестности пикселя) влияют на ваш вывод, если в исходном изображении вокруг вашей области интереса есть пиксели.
Я предлагаю использовать следующее, чтобы изменить порядок памяти перед вызовом cv::dilate()
:
if (!mat.isContinuous() || mat.isSubmatrix())
{
mat = mat.clone();
}