加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

c – 从gpu特征描述符转换的opencv特征描述符的问题

发布时间:2020-12-16 07:00:03 所属栏目:百科 来源:网络整理
导读:我一直在使用openvc将GPU特征描述符矩阵转换为CPU特征描述符矩阵时遇到一些问题,使用: void downloadDescriptors(const GpuMat descriptorsGPU,vectorfloat descriptors); 如您所见,此方法将包含描述符的GpuMat转换为包含它们的浮点数的向量.问题是,当我访
我一直在使用openvc将GPU特征描述符矩阵转换为CPU特征描述符矩阵时遇到一些问题,使用:

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

如您所见,此方法将包含描述符的GpuMat转换为包含它们的浮点数的向量.问题是,当我访问此向量的某个元素时,返回的值与预期的0到255的间隔完全不同.我已经制作了以下测试程序来比较提取时间和通过SURF_GPU和SURF获得的描述:

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,outimageCPU,DrawMatchesFlags::DEFAULT);
imwrite("CPU.jpg",outimageCPU);

return 0;

检查descriptorsConverted的元素,我希望得到0到25??5之间的值,就像我访问descriptorsCPU的元素时得到的那样.相反,我得到的价值如下:

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

我怀疑这个问题与downloadDescriptors返回的类型有关,即使很明显它返回一个浮点向量.

解决方法

我得到了类似描述符的结果,并且在匹配方面遇到了一些初步问题.我发现当描述符被下载到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,descriptorsGPU  );
descriptorsGPU.download( descriptorsCPU );

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读