2016-12-14 7 views
4

Я надеюсь, что этот вопрос не является OT.Какое наиболее эффективное представление матрицы в C++?

Я реализует VLAD кодера с помощью VLFeat implementation и SIFT дескрипторов из различных реализаций их (OpenCV, VLFeat, OpenSIFT) сравнить.

Это должно быть высокопроизводительное приложение на C++ (я знаю, что SIFT очень неэффективен, я реализую его параллельную версию).

Теперь VLAD хочет ввести указатель на набор смежных дескрипторов (математических векторов). Дело в том, что обычно эти дескрипторы SIFT представлены в виде матрицы, поэтому их легче управлять.

Так предположу, что мы имеем матрицу 3 дескрипторов в 3-х измерениях (я использую эти цифры для простоты, на самом деле это тысячи дескрипторов в 128 измерениях):

1 2 3 
4 5 6 
7 8 9 

мне нужно сделать кормить vl_vlad_encode с указателем:

1 2 3 4 5 6 7 8 9 

простое решение является сохранение дескрипторов в cv::Mat m объекта, а затем передать m.data в vl_vlad_encode.

Однако я не знаю, является ли cv::Mat эффективным представлением матрицы. Например, Eigen::Matrix является альтернативой (я думаю, что легко получить представление выше, используя этот объект), но я не знаю, какая реализация выполняется быстрее/эффективнее или есть какая-либо другая причина, потому что я должен предпочесть один вместо Другие.

Другой возможной альтернативой является использование std::vector<std::vector<float>> v, но я не знаю, если с помощью v.data() я бы получить представление выше вместо: 1 2 3 *something* 4 5 6 *something* 7 8 9

Очевидно *something* бы испортить vl_vlad_encode.

Любое другое предложение более чем приветствуется!

+2

'float [9]'?Согласитесь с соглашением о столбцах или строках, а затем вы можете переместить все подряд один столбец или одну строку за другой. –

+0

@ AndonM.Coleman, чтобы объяснить разницу между поплавком [9] и поплавком [3] [3]? Они оба смежные, и соглашение о столбце/строке является изменяемым для обоих. – UKMonkey

+0

Я забыл сказать, что размер матрицы определяется во время выполнения, поэтому использование 'std :: vector v', а затем' v.resize (dim) '(или' v.reserve (dim) ') может быть лучшим решением , где в этом случае «dim = 9». – justHelloWorld

ответ

4

Если вы не сделали какой-нибудь странный материал (см. here), данные в Mat гарантированно будут непрерывными. Вы можете придумать Mat в качестве облегченной обертки над float* (или другими типами), что облегчает доступ к данным. Таким образом, он эффективен как указатель, но с несколькими хорошими абстракциями.

Если вам нужно эффективно загружать/сохранять из/в файл, вы можете сохранить Mat в двоичном формате, используя matread and matwrite.

1

std::vector<std::vector<float>> v не будет работать очень хорошо без каких-либо усилий, так как память не будет смежной.

После того, как ваша память будет непрерывной, будь она float [], float [] [] или std :: array/vector, насколько она будет выполняться, будет зависеть от того, как вы перебираете свою матрицу. Если это случайный доступ, то это мало чем отличается; если вы выполняете итерацию всех столбцов за каждый, то лучше, чтобы ваши данные группировались по столбцу, а не по строке.