4

次のコードを 2 台の異なるコンピューターで実行しています。最初のコンピューターには Nvidia GPU Quadro FX 880M があり、2 番目のコンピューターには Quadro FX 1000M (VS2010 でコンパイル、opencv242,64bit; opencv はソースからコンパイルされています)。私が実行しているコードは次のとおりです。

int n = 1000;  //number of iterations
int t = CV_TM_CCORR_NORMED; //correlation type




//reset GPU, print device info
cv::gpu::printCudaDeviceInfo(cv::gpu::getDevice());
cv::gpu::resetDevice(); 




//read big image
cv::Mat imgA = cv::imread("img.bmp"  ,CV_LOAD_IMAGE_GRAYSCALE);
//read small, template image
cv::Mat imgB = cv::imread("tmplt.bmp",CV_LOAD_IMAGE_GRAYSCALE);




//upload images to GPU
cv::gpu::GpuMat imgA_GPU,imgB_GPU;
imgA_GPU.upload(imgA);
imgB_GPU.upload(imgB);





cv::gpu::GpuMat imgC_GPU; //correlation results, computer in GPU
cv::Mat         imgC_CPU; //correlation results, computer in CPU




//matchTemplate in GPU, print average time(mSec)
size_t t1 = clock();
for(int i = 0;i!=n;++i)
    cv::gpu::matchTemplate(imgA_GPU , imgB_GPU, imgC_GPU , t);

std::cout << "GPU: " <<
(double(clock())-t1)/CLOCKS_PER_SEC*1000.0/n <<std::endl;





//matchTemplate in CPU, print average time(mSec)
size_t t2 = clock();
for(int i = 0;i!=n;++i)
    cv::     matchTemplate(imgA     , imgB    , imgC_CPU , t);

std::cout << "CPU: " <<
(double(clock())-t2)/CLOCKS_PER_SEC*1000.0/n <<std::endl;






//download GPU image to host
cv::Mat imgC_GPUhost;
imgC_GPU.download(imgC_GPUhost);




//convert images to 8U
imgC_CPU.convertTo(imgC_CPU,CV_8U,255);
imgC_GPUhost.convertTo(imgC_GPUhost,CV_8U,255);




//!!!!!! imgC_GPUhost should be equal to imgC_CPU
cv::Mat diff;
cv::absdiff(imgC_CPU,imgC_GPUhost,diff);
//expected: RESULTS DIFF: 0
std::cout << "RESULTS DIFF: " << cv::sum(diff).val[0] << std::endl;





cv::imwrite("cor2.bmp",imgC_CPU);
cv::imwrite("cor.bmp",imgC_GPUhost);
char s;
std::cin >> s;

私を困惑させる2つの主要なことがあります:

  1. Quadro FX 880M では、この関数は機能しません: GPU 出力イメージ (imgC_GPU) はすべてゼロです。入力タイプ (8U または 32F) または相関方法 (ccor、ccoef など) は関係ありません。一方、Quadro FX 1000M では、CPU と GPU の間で一貫した結果が得られます。Quadro FX 880M で動作させるにはどうすればよいですか?

  2. テンプレート マッチングでは、出力画像のすべてのピクセルを他のピクセルとは独立して計算できます。したがって、並列処理は簡単で、GPU の実装は完全に適しています。平均時間を (コードのように) 見ても、GPU のパフォーマンスが CPU の 3 倍遅いということはどうして可能なのでしょうか? 両方のコンピューターで検証され、バックグラウンドで他のプロセスが実行されていません。

オハッド

4

1 に答える 1

0

GPU版のmatchTemplateは、複数のテンプレートを同時に検索することを想定して開発されたようです。確かに、1 つのイメージ/1 つのテンプレートでは、CPU バージョンの方が高速に見えます。

http://answers.opencv.org/question/16061/opencv-matchtemplate-cuda-large-images-templates/

于 2015-02-16T11:46:45.170 に答える