I create a short example of(in my opinion) bad behavior of dilate
cv::Mat input(cv::Size(14, 14), CV_8U, cv::Scalar(0));
input.colRange(10, 14) = cv::Scalar(255);
cv::line(input, cv::Point(1, 3), cv::Point(15, 17), cv::Scalar(255));
cv::Range range(0, 10);
cv::Mat inputRoi = input.colRange(range);
cv::Mat kernel = cv::getStructuringElement(cv::MorphShapes::MORPH_ELLIPSE, cv::Size(5, 5));
cv::Mat dilated;
cv::dilate(inputRoi, dilated, kernel, cv::Point(-1, -1), 1, cv::BORDER_CONSTANT, cv::Scalar::all(0));
On image you can see that dilated mat has last two columns white insted of black. Because, when you dilate submatrix created by colRange it is still pointed to origin mat data and this data is propagate to dilate result. I dont understand why.
My hot fix is clone input mat. But it is not effective way:
cv::Mat input(cv::Size(14, 14), CV_8U, cv::Scalar(0));
input.colRange(10, 14) = cv::Scalar(255);
cv::line(input, cv::Point(1, 3), cv::Point(15, 17), cv::Scalar(255));
cv::Range range(0, 10);
cv::Mat inputRoi = input.colRange(range);
cv::Mat kernel = cv::getStructuringElement(cv::MorphShapes::MORPH_ELLIPSE, cv::Size(5, 5));
cv::Mat dilated;
cv::Mat inputRoiClone = inputRoi.clone();
cv::dilate(inputRoiClone, dilated, kernel, cv::Point(-1, -1), 1, cv::BORDER_CONSTANT, cv::Scalar::all(0));