Using C ++ to rewrite the opencv surf algorithm example (find_obj)
Creation
After opencv 2.0, a large number of standard template class STL were used, and the image structure was unified to mat, and the SURF class was provided. The find_obj.cpp contained in opencv2.2 was actually mainly written in C structure, I have never found the corresponding C ++ example.
So I took the time to rewrite it. For the sake of simplicity, I deleted the brute force matching without FLANN and did not perform plane ing. The code is for reference only.
#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);}
The performance of images in the example is as follows:
The C executable program that comes with opencv:
Object descriptors: 593
Image descriptors: 782
Extraction time = 363.425 Ms
Using approximate Nearest Neighbor Search
Re-compiled debug version
Object descriptors: 593
Image descriptors: 782
Extraction time = 1316.22 Ms
Using approximate Nearest Neighbor Search
Rewrite C ++ code
Note that the flat ing function is less than that of the original example. Only the corresponding vertex is extracted and displayed.
Debug 1820.17 Ms
Release 402.799 Ms