2014-07-17 15 views
5

Sto cercando di eseguire l'algoritmo ORB OpenCV sui frame di un video e ho notato che la versione della CPU è molto più veloce della versione GPU. Ecco il codice:Implementazione GPU OpenCV ORB più lenta della 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; 
} 

Dopo l'esecuzione di questo su un video con 3000 cornici e risoluzione 720x480, il tempo di GPU è di 54 sec e il tempo di CPU 24 sec. Ottengo risultati simili con altri video (non HD). spec PC:

  • i7-4770K CPU 3,50 GHz

  • NVIDIA GeForce GTX 650

  • 16 GB di RAM

Altre funzionalità di rilevamento/Descrizione algoritmi come SURF eseguire più velocemente con l'implementazione della GPU sulla mia macchina.

Qualcuno ha confrontato le due implementazioni di ORB sulla sua macchina?

risposta

4

Tratto da this post:

cv::ORB applica un GaussianBlur (circa 20 righe dalla fine del orb.cpp) prima di descrittori di calcolo. Non c'è modo di controllare questo attraverso l'interfaccia pubblica.

cv::gpu::ORB_GPU ha un membro di public bool blurForDescriptor, che dai costrutti di default come false. Quando lo imposto invece su true, I trova che la distanza min/avg/max di hamming scende a 0/7.2/30 bit, il che sembra molto più ragionevole.

Problemi correlati