4

以下を使用して、openvcを使用してGPU機能記述子マトリックスをCPU機能記述子マトリックスに変換する際に問題が発生しました。

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

ご覧のとおり、このメソッドは、記述子を保持しているGpuMatを、記述子を保持しているfloatのベクトルに変換します。0問題は、このベクトルの一部の要素にアクセスすると、返される値が〜の予想される間隔とはかなり異なること255です。抽出の時間を比較するために次のテストプログラムを作成しまし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の間の値を取得することを期待していました。代わりに、次のような値を取得しました。0255descriptorsCPU

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

この問題はdownloadDescriptors、floatベクトルを返すことは明らかですが、によって返される型に関連していると思われます。

4

1 に答える 1

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] );

また、記述子 GPU から記述子 CPU へのアップロードも同じことを行い、おそらくより安全であることがわかりました。

std::vector<cv::KeyPoint> keypoints;
cv::gpu::GpuMat descriptorsGPU
surfGPU( imgGPU, cv::gpu::GpuMat(), keypoints, descriptorsGPU  );
descriptorsGPU.download( descriptorsCPU );
于 2013-03-19T19:41:57.590 に答える