Есть ли ошибка при использовании заголовка по сравнению с исходным кодом полной матрицы?

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));

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();
}
0

Другие решения


По вопросам рекламы [email protected]