2016-09-13 3 views
1

데이터 세트의 각 이미지에 대해 타임 스탬프와 파일 이름이 저장되는 RGB-D 카메라와 텍스트 파일로 데이터 세트를 얻습니다. 내가하는 일은이 파일을 파싱하고 두 개의 std :: map을 채우는 것이다. 하나는 rgb 이미지 용이고 다른 하나는 깊이 이미지 용이다. 이제는 타임 스탬프가 교차하지 않기 때문에 타임 스탬프를 기반으로 일치하는 이미지를 찾는 루틴을 작성해야합니다. 이것은 내가 지금까지 쓴 것입니다 :두 표준 사이의 일치를 찾는 C++ 효율적인 방법

typedef map<double,string> StampImageMap; 

... 

vector<string> &vstrImageFilenamesRGB; 
vector<string> &vstrImageFilenamesD; 
vector<double> &vTimestampsRGB; 
vector<double> &vTimestampsDPT; 

double tolerance = 0.02; 

for(StampImageMap::iterator it=rgb_images.begin(); it != rgb_images.end(); it++) { 
     bool found = false; 
     StampImageMap::iterator jt=depth_images.begin(); 
     while(found == false && jt!=depth_images.end()) { 
      if(fabs(it->first - jt->first) < tolerance) { 
       found = true; 
       vstrImageFilenamesRGB.push_back(it->second); 
       vstrImageFilenamesD.push_back(jt->second); 
       vTimestampsRGB.push_back(it->first); 
       vTimestampsDPT.push_back(jt->first); 
      } 
      jt++; 
     } 
    } 

이 작업을 수행하는 더 효율적인 방법이 있는지 궁금합니다. 코드가 현재 기록되면

+0

당신이 RGB 및 D 타임 스탬프에 대한 일대일 관계를 가지고 수행이 경우에 대한 의사 여기

입니까? 그들은 고정 된 규칙을 따릅니 까? RGB 타임 스탬프는 항상 같은 이미지의 D 타임 스탬프보다 작습니까? –

+0

예 카메라의 프레임 속도가 30Hz이므로 해당 RGB 및 DEPTH 이미지의 타임 스탬프가 동일하지는 않지만 그 차이는 1/33을 초과 할 수 없기 때문에 가변 공차를 설정합니다 . –

+0

@FedericoNardi 시퀀스가 ​​"완료"(하나의 간격 없음) 및 일대일로 수행되는 경우 가장 오래된 일치 항목을 찾은 다음 순서대로 나열 할 수 있습니까? (즉, 첫 번째 깊이 이미지가있는 첫 번째 rgb 이미지, 두 번째 이미지가있는 두 번째 이미지 등) – molbdnilo

답변

2

는 복잡성 N, m은 시퀀스의 크기이다 Θ (n 개의 m)이다. 이를 개선하는 방법은 두 가지가 있습니다 (두 번째 방법이 더 효율적이지만 코드 작성이 더 어렵습니다). 외부 루프의 본문

  • , while(found == false && jt!=depth_images.end()) 통해 제 2 맵 내의 모든 요소를 ​​수행하지 루프. 대신 it->first - toleranceit->first + tolerance을 검색하려면 std::map::lower_boundstd::map::upper_bound을 사용하십시오. 이 두 호출의 결과 사이에서만 반복하십시오.

    for(StampImageMap::iterator it=rgb_images.begin(); it != rgb_images.end(); it++) { 
        StampImageMap::const_iterator lower = depth_images.lower_bound(it->first - tolerance); 
        StampImageMap::const_iterator upper = depth_images.lower_bound(it->first + tolerance); 
    
        // Now just search between lower and upper. 
    } 
    

    P이 범위의 크기 Θ (로그 (m)) + P에 각각의 반복을 감소 :

    따라서, 코드는 다음과 같이된다.

  • 지도의 키가 정렬되었으므로 standard technique of finding the intersection of two sorted arrays을이 경우로 수정할 수 있습니다. 이렇게하면 실행 시간이 Θ (m + n)으로 줄어 듭니다. 수정 사항은 정확한 요소의 교차점을 찾는 것이 아니라 "충분히 근접한"요소의 교차점을 찾기 위해 조금 까다 롭습니다.

    it = rgb_image.begin(); 
    jt = depth_image.begin(); 
    
    while(it != rgb_image.end() && jt != depth_image.end()) { 
        if(fabs(it->first - jt->first) < tolerance) { 
         // Match found! 
         ++it; 
         ++jt; 
         continue; 
        } 
    
        if(it.first > jt.first + tolerance) { 
         ++jt; 
         continue; 
        } 
    
        ++it; 
    } 
    
+0

허용 오차 내에서 비교를 처리 할 특수 비교기를 작성해야합니다 (간단합니다.이미 OP 코드에서 수행됨) - 전이 적이 지 않지만 맵의 모든 값에 적용되며 이는 중요한 요소입니다. 또한 지원자가 필요로하는 것을 수행하는 특수 출력 반복기를 사용하면 표준 라이브러리를 쉽게 사용할 수 있습니다 . –

+0

@Revolver_Ocelot 맞아, 좋은 생각이야. 그러나 세부 사항에 대해 인내심을 가지고 있다면 두 번째 것은 더 낮은 복잡성을 가지며 이에 대한 표준 라이브러리 알고리즘이 있는지 확신하지 못합니다 (비교 기능에 대한 올바른 지적은 사실입니다). –

+0

아, 두 맵의 값이 필요하기 때문에 set_intersection을 사용할 수 없다는 것을 알아 냈습니다. 나중에 두 번째 맵을 반복 할 수는 있지만 알고리즘은 O (nm)보다 여전히 느려 속도가 느려서 기본적으로 솔루션은 set_intersection이지만 한 번에 두 값을 처리합니다. –

관련 문제