Преобразование совпадений из 8-битных 4 каналов в 64-битные 1 канал в OpenCV

У меня есть vector из Point2f, которые имеют цветовое пространство CV_8UC4, и мне нужно преобразовать их в CV_64F, правильный ли следующий код?

points1.convertTo(points1, CV_64F);

Подробнее:

Я пытаюсь использовать эту функцию для вычисления основной матрицы (поворот/перевод) с помощью 5-точечного алгоритма вместо использования findFundamentalMath, включенного в OpenCV, который основан на 8-точечном алгоритме:

https://github.com/prclibo/relative-pose-estimation/blob/master/five-point-nister/five-point.cpp#L69

Как видите, сначала он преобразует изображение в CV_64F. Мое входное изображение - это изображение CV_8UC4, BGRA. Когда я тестировал функцию, изображения в BGRA и оттенках серого давали правильные матрицы с математической точки зрения, но если я передаю изображение в градациях серого вместо цвета, для вычисления требуется гораздо больше времени. Что заставляет меня думать, что я что-то не так делаю в одном из двух случаев.

Я читал, что когда изменение цветового пространства не является линейным (что, я полагаю, происходит, когда вы переходите с 4 каналов на 1, как в этом случае), вы должны нормализовать значение интенсивности. Это правильно? Какой вход я должен дать этой функции?

Еще одно замечание, в моем коде функция вызывается так:

vector<Point2f>imgpts1, imgpts2;

for (vector<DMatch>::const_iterator it = matches.begin(); it!= matches.end(); ++it)
{
  imgpts1.push_back(firstViewFeatures.second[it->queryIdx].pt);
  imgpts2.push_back(secondViewFeatures.second[it->trainIdx].pt);
}

Mat mask;
Mat E = findEssentialMat(imgpts1, imgpts2, [camera focal], [camera principal_point], CV_RANSAC, 0.999, 1, mask);

Тот факт, что я передаю не Mat, а вместо этого vector из Point2f, кажется, не создает проблем, поскольку он компилируется и выполняется правильно.

Это тот случай, когда я должен хранить спички в Mat?


person aledalgrande    schedule 29.05.2014    source источник


Ответы (2)


Я не уверен, что вы имеете в виду под вектором Point2f в каком-то цветовом пространстве, но если вы хотите преобразовать вектор точек в вектор точек другого типа, вы можете использовать любую стандартную функцию C++/STL, такую ​​как copy(), assign() или вставлять(). Например:

copy(floatPoints.begin(), floatPoints.end(), doublePoints.begin());

or

doublePoints.insert(doublePoints.end(), floatPoints.begin(), floatPoints.end());
person Michael Burdinov    schedule 29.05.2014
comment
Это не совсем то, что меня интересует этим вопросом. Пожалуйста, смотрите обновление. - person aledalgrande; 29.05.2014

Нет это не так. std::vector<cv::Pointf2f> не может использовать функцию OpenCV convertTo.

Я думаю, вы действительно имеете в виду, что у вас есть cv::Mat points1 типа CV_8UC4. Обратите внимание, что это RxCx4 значений (то есть R и C количество строк и столбцов), и что в матрице CV_64F у вас будет только RxC значений. Итак, вам нужно более четко представлять, как вы хотите преобразовать эти значения.

Вы можете сделать points1.convertTo(points1, CV_64FC4), чтобы получить матрицу RxCx4.

Обновление:

Некоторые замечания после того, как вы обновили вопрос:

Обратите внимание, что vector<cv::Point2f> — это вектор 2D-точек, который не связан с каким-либо конкретным цветовым пространством, это просто координаты на осях изображения. Таким образом, они представляют одни и те же 2D-точки на сером, rgb или hsv изображении. Тогда время выполнения findEssentialMat не зависит от цветового пространства изображения. Однако получение очков может.

Тем не менее, я думаю, что ваш ввод для findEssentialMat в порядке (функция заботится о векторах и преобразует их во внутреннее представление). В этом случае очень полезно рисовать точки на изображении для отладки кода.

person ChronoTrigger    schedule 29.05.2014
comment
Я добавил больше деталей к вопросу. - person aledalgrande; 29.05.2014