用C++重写了OPENCV SURF算法例子

来源:互联网 发布:温故知今txt下载 编辑:程序博客网 时间:2024/05/21 10:24
 

用C++重写了OPENCV SURF算法例子(find_obj)
2012-2-7 创建

OPENCV 2.0后大量使用了标准模板类STL,而且图像结构统一为Mat,并提供了SURF类,而OPENCV2.2中带有的find_obj.cpp实际上还是主要使用c结构编写的,我也一直没有找到相对应C++例子
因此花时间改写了一下,为了例子的简洁,删除了不使用FLANN的brute force matching,而且没有进行平面映射,代码仅供参考

#include <iostream>#include <opencv2/opencv.hpp>using namespace cv;using namespace std;void newFlannFindPairs(const vector<KeyPoint>& obj_keypoints,     const vector<float>& obj_descriptors,      const vector<KeyPoint>& img_keypoints,      const vector<float>& img_descriptors,      vector<int>& ptpairs ){// find nearest neighbors using FLANNint length = obj_descriptors.size() / obj_keypoints.size();cv::Mat m_object(obj_keypoints.size(), length, CV_32F);cv::Mat m_image(img_keypoints.size(), length, CV_32F);cv::Mat temp_object(obj_descriptors, true);cv::Mat temp_image(img_descriptors, true);//Use memcpy to keep Mat sizememcpy(m_object.data, temp_object.data, temp_object.total() * sizeof(float));memcpy(m_image.data, temp_image.data, temp_image.total() * sizeof(float));//FLANNcv::Mat m_indices(obj_keypoints.size(), 2, CV_32S);cv::Mat m_dists(obj_keypoints.size(), 2, CV_32F);cv::flann::Index flann_index(m_image, cv::flann::KDTreeIndexParams(4));  // using 4 randomized kdtreesflann_index.knnSearch(m_object, m_indices, m_dists, 2, cv::flann::SearchParams(64) ); // maximum number of leafs checked//Save to point pairsint* indices_ptr = m_indices.ptr<int>(0);float* dists_ptr = m_dists.ptr<float>(0);for (int i=0;i<m_indices.rows;++i) {if (dists_ptr[2*i]<0.6*dists_ptr[2*i+1]) {ptpairs.push_back(i);ptpairs.push_back(indices_ptr[2*i]);}}}int surfTest(const char* object_filename, const char* scene_filename){double tt = (double)cvGetTickCount();Mat obj = imread(object_filename,0);Mat img = imread(scene_filename,0);if( (img.data == NULL) || (obj.data == NULL) ){cout<<"Unable to read images "<<endl;return 1;}// Create the SURF objectMat obj_mask = 255 * Mat::ones(obj.rows,obj.cols,CV_8U);Mat img_mask = 255 * Mat::ones(img.rows,img.cols,CV_8U);const int HessianThreshold = 500;SURF surf(HessianThreshold);vector<KeyPoint> obj_keypoints;vector<float> obj_descriptors;vector<KeyPoint> img_keypoints;vector<float> img_descriptors;surf(obj, obj_mask, obj_keypoints, obj_descriptors);surf(img, img_mask, img_keypoints, img_descriptors);// Plot the keypointsconst int radius = 1, thickness = 2;const Scalar obj_color(255,0,0,0);const Scalar img_color(0, 255,0,0);vector<int> ptpairs;newFlannFindPairs(obj_keypoints, obj_descriptors, img_keypoints, img_descriptors, ptpairs);double tt_f = (double)cvGetTickCount() - tt;printf( "Extraction pair point time = %gms\n", tt_f/(cvGetTickFrequency()*1000.));Mat correspond = Mat::zeros(img.rows + obj.rows, img.cols, CV_8U);cv::Rect objRect(Point(0, 0), obj.size());Mat objROI = correspond(objRect);obj.copyTo(objROI);cv::Rect imgRect(Point(0, objRect.height), img.size());Mat imgROI = correspond(imgRect);img.copyTo(imgROI);for( int i = 0; i < (int)ptpairs.size(); i += 2 ){Point p1 = Point(cvRound(obj_keypoints[ptpairs[i]].pt.x), cvRound(obj_keypoints[ptpairs[i]].pt.y));Point p2 = Point(cvRound(img_keypoints[ptpairs[i+1]].pt.x), cvRound(img_keypoints[ptpairs[i+1]].pt.y + objRect.height));line(correspond, p1, p2, obj_color);}imshow("SURF_CORRESPOND", correspond);waitKey(0);return 0;}int main(int argc, char** argv){const char* object_filename = argc == 3 ? argv[1] : "../debug/box.png";const char* scene_filename = argc == 3 ? argv[2] : "../debug/box_in_scene.png";return surfTest(object_filename, scene_filename);}


 

 


使用例子带有的图片,性能如下:

OPENCV自带的C可执行程序:
Object Descriptors: 593
Image Descriptors: 782
Extraction time = 363.425ms
Using approximate nearest neighbor search

重新编译的DEBUG版
Object Descriptors: 593
Image Descriptors: 782
Extraction time = 1316.22ms
Using approximate nearest neighbor search

重新改写的C++代码
注意功能比原例子减少了平面映射,只提取对应点并显示
DEBUG 1820.17ms 
RELEASE 402.799ms

原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 饿了么送错单了怎么办 支付宝退款失败怎么办 充话费总是退款怎么办 月初流量不能用怎么办 微信充值话费退款失败怎么办 ios邮件退款失败怎么办 信用卡充了钱怎么办 ios退款被拒绝怎么办 话费缴错了怎么办 网上缴费交错了怎么办 别人给交错话费怎么办 联通流量不到账怎么办 卖家拒绝退款怎么办? 淘宝退款后红包怎么办 手机不能吃鸡怎么办? 在国外手机软件好多不支持怎么办 淘宝店拒绝退款怎么办 app没有退款资格怎么办 手机无法计步怎么办 抖音机型不支持怎么办 用nfc不支持卡片怎么办 移动怎么办省内流量包 手机交不了话费怎么办 淘宝快递不签收怎么办 快递买家不签收怎么办 淘宝退货未收货怎么办 淘宝退衣服运费怎么办 手机流量不到账怎么办 淘宝水果坏了怎么办 用微信充值话费充成空号了怎么办 苹果id被拉黑了怎么办 苹果app不退款怎么办 合同退款不退怎么办 微信充值q币被骗怎么办 小米手机存储空间不够怎么办 小米mix2s存储空间不够怎么办 进货一直没发票怎么办 魅蓝note5卡怎么办 电话费套餐花不了怎么办 墙和床头有间缝怎么办 床板里有虫子怎么办