2014-07-17 11 views
5

Ich versuche, den ORB OpenCV-Algorithmus auf die Frames eines Videos zu laufen, und ich bemerkte, dass die CPU-Version viel schneller als die GPU-Version ausführt. Hier ist der Code:OpenCV ORB GPU-Implementierung langsamer als CPU

#include <iostream> 
#include "opencv2/core/core.hpp" 
#include "opencv2/features2d/features2d.hpp" 
#include "opencv2/highgui/highgui.hpp" 
#include "opencv2/gpu/gpu.hpp" 
#include <fstream> 
#include <sstream> 
#include <math.h> 
#include <omp.h> 

#include <algorithm> 
#include <vector> 
#include <string> 

using namespace cv; 
using namespace std; 
using namespace cv::gpu; 

void process_cpu(string vid, int start_frame, int end_frame) 
{ 
VideoCapture myCapture(vid); 
Mat frame, gray_frame; 
ORB myOrb(400); 
Mat descriptors; 
vector<KeyPoint> keypoints; 

myCapture.set(CV_CAP_PROP_POS_FRAMES, start_frame); 

for (int i=0; i<end_frame-start_frame; i++) { 
    myCapture.read(frame); 
    cvtColor(frame, gray_frame, CV_RGB2GRAY); 
    myOrb(gray_frame, Mat(), keypoints, descriptors); 
} 
myCapture.release(); 
} 

void process_gpu(string vid, int start_frame, int end_frame) 
{ 
VideoCapture myCapture(vid); 
Mat frame, gray_frame; 
GpuMat gpu_frame; 
ORB_GPU myOrb(400); 
GpuMat keypoints, descriptors; 

myCapture.set(CV_CAP_PROP_POS_FRAMES, start_frame); 

for (int i=0; i<end_frame-start_frame; i++) { 
    myCapture.read(frame); 
    cvtColor(frame, gray_frame, CV_RGB2GRAY); 
    gpu_frame.upload(gray_frame); 
    myOrb.blurForDescriptor = true; 
    myOrb(gpu_frame, GpuMat(), keypoints, descriptors); 
} 
myCapture.release(); 
} 

int main (int argc, char* argv[]) 
{ 
int n = 4; 
VideoCapture myCapture(argv[1]); 
double frameNumber = myCapture.get(CV_CAP_PROP_FRAME_COUNT); 
myCapture.release(); 

double TimeStart = 0; 
double TotalTime = 0; 
TimeStart = (double)getTickCount(); 

process_gpu(argv[1], 0, frameNumber); 

TotalTime = (double)getTickCount() - TimeStart; 
TotalTime = TotalTime/getTickFrequency(); 
cout << "Gpu Time : " << TotalTime << endl; 

TimeStart = (double)getTickCount(); 

process_cpu(argv[1], 0, frameNumber); 

TotalTime = (double)getTickCount() - TimeStart; 
TotalTime = TotalTime/getTickFrequency(); 
cout << "Cpu Time : " << TotalTime << endl; 

return -1; 
} 

Danach mit 3000 Frames auf einem Video läuft und 720x480 Auflösung, die GPU Zeit beträgt 54 Sekunden und die CPU-Zeit 24 Sek. Ich bekomme ähnliche Ergebnisse mit anderen Videos (nicht HD). PC-Spezifikationen:

  • i7-4770K CPU 3.50 GHz

  • NVIDIA GeForce GTX 650

  • 16 GB RAM

Weitere Feature-Erkennung/Beschreibung Algorithmen wie SURF führen schneller die GPU-Implementierung auf meiner Maschine.

Hat jemand die beiden Implementierungen von ORB auf seiner Maschine verglichen?

Antwort

4

von this post wurde:

cv::ORB wendet ein Weichzeichnen (etwa 20 Zeilen aus dem Ende des orb.cpp) vor Deskriptoren berechnet wird. Es gibt keine Möglichkeit, dieses über die öffentliche Schnittstelle zu steuern.

cv::gpu::ORB_GPU hat ein öffentliches Mitglied bool blurForDescriptor, die standardmäßig Konstrukte als false. Wenn ich es stattdessen auf true setze, finde ich, dass die min/avg/max-Hamming-Distanz auf 0/7,2/30 Bits fällt, was viel vernünftiger erscheint.