2016-12-14 11 views
4

나는이 질문이 구약이 아니 길 바랍니다.C++에서 가장 효율적인 행렬 표현은 무엇입니까?

나는 그들 (OpenCV의, VLFeat, OpenSIFT)을 비교하기 위해 다른 구현에서 VLFeat implementationSIFT 디스크립터를 사용하여 VLAD 인코더를 구현하고 있습니다.

이것은 C++에서 고성능 응용 프로그램으로 간주됩니다 (SIFT가 매우 비효율적이며, 병렬 버전을 구현하고 있음을 알고 있습니다).

이제 VLAD는 일련의 연속 된 설명자 (수학 벡터)에 대한 포인터를 입력으로 원합니다. 요컨대이 SIFT 디스크립터는 일반적으로 행렬로 표현되므로 관리하기가 더 쉽습니다.

그래서 우리는 (나는 실제로 128 개 차원에서 설명 수천의, 단순성을 위해이 숫자를 사용하고 있습니다) 3 차원 3 개 기술자의 행렬을 가지고 랬 :

1 2 3 
4 5 6 
7 8 9 

내가 할 필요가 cv::Mat m 객체에

1 2 3 4 5 6 7 8 9 

간단한 솔루션을 절약 설명하고 vl_vlad_encodem.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은 float [9]와 float [3] [3]의 차이점을 설명합니다. 둘 다 인접하고 열/행 규칙은 둘 다 변경할 수 있습니다. – UKMonkey

+0

행렬 차원이 런타임에 결정된다는 것을 잊어 버렸기 때문에'std :: vector v' 그리고'v.resize (dim)'(또는'v.reserve (dim)')를 사용하는 것이 더 나은 해결책이 될 수 있습니다. 이 경우 dim = 9입니다. – justHelloWorld

답변

4

이상한 것을하지 않으면 (here 참조), Mat의 데이터는 연속성이 보장됩니다. 데이터에 더 쉽게 액세스 할 수 있도록 float* (또는 다른 유형) 이상의 경량 랩퍼로 Mat을 생각할 수 있습니다. 포인터만큼이나 효율적이지만 추상화가 잘되어 있습니다.

파일을 효율적으로로드/저장하려면 matread and matwrite을 사용하여 Mat을 이진 형식으로 저장할 수 있습니다.

1

std::vector<std::vector<float>> v은 메모리가 인접하지 않기 때문에 약간의 노력 없이는 잘 수행하지 못할 것입니다.

일단 메모리를 연속 시키면 float [], float [] [] 또는 std :: array/vector가됩니다. 얼마나 잘 수행 할지는 매트릭스를 반복하는 방법에 따라 달라집니다. 랜덤 액세스 인 경우에는 별 차이가 없습니다. 그렇다면 모든 열을 반복하는 경우 행 대신 열별로 데이터를 그룹화하는 것이 좋습니다.