2012-05-23 103 views
4

我一直有一些問題與GPU功能描述矩陣與openvc一個CPU特徵描述矩陣轉換,使用:與OpenCV的特徵描述的問題,從GPU的特徵描述信息轉換

void downloadDescriptors(const GpuMat& descriptorsGPU, vector<float>& descriptors); 

,你可以看,這個方法轉換GpuMat持有描述符爲一個載體的花車矢量。問題是,當我訪問這個向量的某個元素時,返回的值與0255的預期區間完全不同。我做了以下測試程序來比較提取和描述的通過SURF_GPUSURF獲得的時間:

clock_t start; 
clock_t end; 

SURF_GPU surfGPU; 
SURF surf; 

Mat img1 = imread("Ipo_SP_01.jpg", CV_LOAD_IMAGE_GRAYSCALE); 
Mat outimageGPU; 
Mat outimageCPU; 
GpuMat imgGPU; 
imgGPU.upload(img1); 

vector<KeyPoint> keyp_A; 
vector<KeyPoint> keyp_B; 
GpuMat keypGPU; 

vector<float> descriptorsConverted; 
Mat descriptorsCPU; 
GpuMat descriptorsGPU; 

start = (clock() * 1000)/CLOCKS_PER_SEC; 
surfGPU(imgGPU, GpuMat(), keypGPU, descriptorsGPU); 
end = (clock() * 1000)/CLOCKS_PER_SEC; 
cout << "GPU time: " << end - start << endl; 
surfGPU.downloadKeypoints(keypGPU, keyp_A); 
surfGPU.downloadDescriptors(descriptorsGPU, descriptorsConverted); 
cout << "GPU Keypoints = " << keyp_A.size() << endl; 

start = (clock() * 1000)/CLOCKS_PER_SEC; 
surf(img1, Mat(), keyp_B, descriptorsCPU); 
end = (clock() * 1000)/CLOCKS_PER_SEC; 
cout << "CPU time: " << end - start << endl; 
cout << "CPU Keypoints = " << keyp_B.size() << endl; 

drawKeypoints(img1, keyp_A, outimageGPU, Scalar(255, 255, 255), DrawMatchesFlags::DEFAULT); 
imwrite("GPU.jpg", outimageGPU); 
drawKeypoints(img1, keyp_B, outimageCPU, Scalar(255, 255, 255), DrawMatchesFlags::DEFAULT); 
imwrite("CPU.jpg", outimageCPU); 

return 0; 

檢查的descriptorsConverted的元素,我希望0255之間得到的值,比如我是說我訪問descriptorsCPU的元素。相反,我喜歡的值:

-0.000621859 
0.000627841 
-0.000503146 
0.000543773 
-8.69408e-05 
0.000110254 
0.000265697 
0.000941789 
0.0595061 
0.0619723 

我懷疑這個問題是關係到由downloadDescriptors返回的類型,即使它很清楚它返回一個浮點矢量。

+0

我的猜測是,值於浮在0和1之間的歸一化(的 - 可能被舍入誤差)。你嘗試乘以255和舍入(比較)? –

+0

我確實是。價值仍然很奇怪,主要是因爲有負數和正數。此外,當乘以255時,大多數值仍然在0和1之間,那些將舍入爲0. –

+0

所有負值都舍入爲零嗎?對於其他值,你是否注意到float版本(縮放到255)比CPU版本有更多的0?我認爲在SURF描述符中有很多零可能是正常的。 –

回答

1

我得到了類似的描述符結果,並且在匹配時遇到了一些初始問題。我已經發現,當描述符被下載到std::vector<float> f_descriptors該矢量的長度是由描述符尺寸整除(即,64或128),因此我能夠使用下面的:

std::vector<float> f_descriptors; 
std::vector<cv::KeyPoint> keypoints; 
surfGPU(imgGPU, cv::gpu::GpuMat(), keypoints, f_descriptors ); 
descriptorsCPU = cv::Mat((int)f_descriptors.size()/surfGPU.descriptorSize(), surfGPU.descriptorSize(), CV_32F, f_descriptors[0]); 

另外,我發現,從descriptorsGPU到descriptorsCPU上傳也做了同樣的事情,可能是更安全:

std::vector<cv::KeyPoint> keypoints; 
cv::gpu::GpuMat descriptorsGPU 
surfGPU(imgGPU, cv::gpu::GpuMat(), keypoints, descriptorsGPU ); 
descriptorsGPU.download(descriptorsCPU);