#c #opencv
#c #opencv
Вопрос:
Это было запущено с использованием OpenCV 4.0.1. Не уверен в предыдущих версиях.
Приведенный ниже код показывает, что расширение OpenCV и, я думаю, morphologyEx в целом не возвращают одинаковые результаты при вычислении на подматрице по сравнению с клоном той же матрицы. Похоже, что он использует значения вне подматрицы для вычисления граничных значений результата.
Короче говоря, v2in и v3in эквивалентны, но v2in состоит из подматрицы v1, тогда как v3in является ее клоном. Тем не менее, расширение двух элементов дает разные результаты, когда расширение v2in, по-видимому, неправильно использует данные, а не в v2in, взятые из элементов v1in, смежных с данными v2in.
// dilation of a 1x7 "vector" works as expected.
Mat_<uchar> vin1 = (Mat_<uchar>(1, 7) << 0,0,0,1,0,0,0);
std::cout << "vin1:" << vin1 << std::endl;
Mat_<uchar> vout1;
morphologyEx(vin1, vout1, MORPH_DILATE, Mat::ones(1, 5, CV_8UC1));
std::cout << "vout1:" << vout1 << std::endl;
// Changing the edge values of v1in1.
Mat_<uchar> vin2;
vin1(0) = 255; vin1(6) = 128;
// creating v2 as a subset of v1 that doesn't include it edge elements (v1 elts 0 and 6)
vin2 = vin1.colRange(1, 6);
// printing the state of things. Comfirming that v2 is in fact a sub-matrix of 1 that doesn't include the
// edge (v1 elts 0 and 6) values of vin1
std::cout << "in1(0) = 255; vin1(6) = 128 modified vin1= " << vin1 << std::endl;
std::cout << "vin1.datastart= " << std::hex << static_cast<const void*>(vin1.datastart) << std::endl;
std::cout << "vin2=vin1.colRange(1, 6), vin2=" << vin2 << std::endl;
std::cout << "vin2.datastart= " << std::hex << static_cast<const void*>(vin2.datastart) << std::endl;
std::cout << "vin2.data= " << std::hex << static_cast<void*>(vin2.data) << std::endl;
// dilation of v2, in vout2, uses the data not in v2, taken from v1 elts 0 and 6 yielding bad results.
Mat_<uchar> vout2;
morphologyEx(vin2, vout2, MORPH_DILATE, Mat::ones(1, 5, CV_8UC1));
std::cout << "Dilate of vin2=vin1.colRange(1, 6), vout2= " << vout2 << std::endl;
Mat_<uchar> vin3 = vin1.colRange(1, 6).clone();
// But doing the same dilation using a clone vs a submatrix gives a different, and correct, answer.
std::cout << "vin3=vin1.colRange(1, 6).clone(), vin3=" << vin3 << std::endl;
Mat_<uchar> vout3;
morphologyEx(vin3, vout3, MORPH_DILATE, Mat::ones(1, 5, CV_8UC1));
std::cout << "Dilate of vin3=vin1.colRange(1, 6).clone(), vout3" << vout3 << std::endl;
Вывод:
vin1:[ 0, 0, 0, 1, 0, 0, 0]
vout1:[ 0, 1, 1, 1, 1, 1, 0]
in1 (0) = 255; vin1 (6) = 128 модифицированный vin1= [255, 0, 0, 1, 0, 0, 128]
vin1.datastart= 000001DC6A628FC0
vin2=vin1.colRange (1, 6), vin2=[ 0, 0, 1, 0, 0]
vin2.datastart= 000001DC6A628FC0
vin2.data= 000001DC6A628FC1
Расширение vin2=vin1.colRange (1, 6), vout2= [255, 255, 1, 128, 128]
vin3=vin1.colRange(1, 6).clone(), vin3=[ 0, 0, 1, 0, 0]
Расширение vin3=vin1.colRange(1, 6).clone(), vout3[ 1, 1, 1, 1, 1]
Комментарии:
1. Вы проверили
borderType
параметрыmorphologyEx()
? Я думаю, что ознакомление с документами ответит на ваши вопросы: docs.opencv.org/master/d4/d86 /… .borderType
Параметр используется в ряде мест в OpenCV, иcv::BorderTypes
перечисление описывает, как каждый из них работает с простыми строковыми примерами: docs.opencv.org/3.4/d2/de8 /…2. Спасибо. Я не заметил флаг / опцию BORDER_ISOLATED MUXable, который, как говорится, если я его не упускаю, ни это, ни документ morphologyEx не объясняет это как значение по умолчанию, что, я думаю, проблематично в контексте того же документа, в котором граница по умолчанию указана как BORDER_CONSTANT (что, по крайней мере, на первый взгляд, не было бы согласованным.)