Showing posts with label matching. Show all posts
Showing posts with label matching. Show all posts

11/03/2014

OpenCV EMD(earth mover distance) example source code

EMD(earth mover distance) method is very good method to compare image similarity.
But processing time is slow.
For using the EMD compare, we should make signature value.
The EMD method compares two signatures value.

Firstly, we prepare histograms of 2 images.
And convert values of histrogram to signature.

A configuration of signature values is very simple.

bins value, x index, y index.
bins value, x index, y index.
bins value, x index, y index.
bins value, x index, y index.
bins value, x index, y index.
....

Of course this type is in case of 2d histogram.
More detail, see the source code.

In here I cannot explain earth mover distance algorithm.
please refer to internet information.

thank you.


origin images
 
result


...
#include < iostream>
#include < vector>

#include < stdio.h>      
#include < opencv2\opencv.hpp>    


#ifdef _DEBUG           
#pragma comment(lib, "opencv_core249d.lib")   
#pragma comment(lib, "opencv_imgproc249d.lib")   //MAT processing   
#pragma comment(lib, "opencv_highgui249d.lib")   
#else   
#pragma comment(lib, "opencv_core249.lib")   
#pragma comment(lib, "opencv_imgproc249.lib")      
#pragma comment(lib, "opencv_highgui249.lib")   
#endif   


using namespace cv;   
using namespace std;   
  
  
  
int main()   
{   

 //read 2 images for histogram comparing   
 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////   
 Mat imgA, imgB;   
 imgA = imread(".\\image1.jpg");   
 imgB = imread(".\\image2.jpg");   


 imshow("img1", imgA);
 imshow("img2", imgB);


 //variables preparing   
 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////   
 int hbins = 30, sbins = 32;    
 int channels[] = {0,  1};   
 int histSize[] = {hbins, sbins};   
 float hranges[] = { 0, 180 };   
 float sranges[] = { 0, 255 };   
 const float* ranges[] = { hranges, sranges};    

 Mat patch_HSV;   
 MatND HistA, HistB;   

 //cal histogram & normalization   
 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////   
 cvtColor(imgA, patch_HSV, CV_BGR2HSV);   
 calcHist( &patch_HSV, 1, channels,  Mat(), // do not use mask   
  HistA, 2, histSize, ranges,   
  true, // the histogram is uniform   
  false );   
 normalize(HistA, HistA,  0, 1, CV_MINMAX);   


 cvtColor(imgB, patch_HSV, CV_BGR2HSV);   
 calcHist( &patch_HSV, 1, channels,  Mat(),// do not use mask   
  HistB, 2, histSize, ranges,   
  true, // the histogram is uniform   
  false );   
 normalize(HistB, HistB, 0, 1, CV_MINMAX);   

 //compare histogram   
 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////   
 int numrows = hbins * sbins;

 //make signature
 Mat sig1(numrows, 3, CV_32FC1);
 Mat sig2(numrows, 3, CV_32FC1);

 //fill value into signature
 for(int h=0; h< hbins; h++)
 {
  for(int s=0; s< sbins; ++s)
  {
   float binval = HistA.at< float>(h,s);
   sig1.at< float>( h*sbins + s, 0) = binval;
   sig1.at< float>( h*sbins + s, 1) = h;
   sig1.at< float>( h*sbins + s, 2) = s;

   binval = HistB.at< float>(h,s);
   sig2.at< float>( h*sbins + s, 0) = binval;
   sig2.at< float>( h*sbins + s, 1) = h;
   sig2.at< float>( h*sbins + s, 2) = s;
  }
 }

 //compare similarity of 2images using emd.
 float emd = cv::EMD(sig1, sig2, CV_DIST_L2); //emd 0 is best matching. 
 printf("similarity %5.5f %%\n", (1-emd)*100 );
 
 waitKey(0);   

 return 0;   
}  

...

7/28/2014

(OpenCV Study) OpticalFlow Gpu feature extraction and matching (GoodFeaturesToTrackDetector_GPU, gpu:: PyrLKOpticalFlow example source code)

This is example source code of Gpu mode optical flow and matching.
Source code is little bit complex in matching refine part.


function of BruteForceMatcher_GPU is added for more accurate matching.
The result is like that.


The source code is here..

...
Mat Ma = Mat::eye(3, 3, CV_64FC1);
 cout << Ma << endl;
 double dm[3][3] = { { 1, 2, 3 }, { 4, 5, 6 }, { 7, 8, 9 } };
 Mat Mb = Mat(3, 3, CV_64F, dm);
 cout << Mb << endl;
 
 //Matrix - matrix operations :
 Mat Mc;
 cv::add(Ma, Mb, Mc); // Ma+Mb   -> Mc
 cout << Ma+Mb << endl;
 cout << Mc << endl;
 cv::subtract(Ma, Mb, Mc);      // Ma-Mb   -> Mc
 cout << Ma - Mb << endl;
 cout << Mc << endl;
 Mc = Ma*Mb; //Ma*Mb;
 cout << Mc << endl;
 
 //Elementwise matrix operations :
 cv::multiply(Ma, Mb, Mc);   // Ma.*Mb   -> Mc
 cout << Mc << endl;
 Mc = Ma.mul(Mb);
 cout << Mc << endl;
 cv::divide(Ma, Mb, Mc);      // Ma./Mb  -> Mc
 cout << Mc << endl;
 Mc = Ma + 10; //Ma + 10 = Mc
 cout << Mc << endl;

 //Vector products :
 double va[] = { 1, 2, 3 };
 double vb[] = { 0, 0, 1 };
 double vc[3];

 Mat Va(3, 1, CV_64FC1, va);
 Mat Vb(3, 1, CV_64FC1, vb);
 Mat Vc(3, 1, CV_64FC1, vc);

 double res = Va.dot(Vb); // dot product:   Va . Vb -> res
 Vc = Va.cross(Vb);    // cross product: Va x Vb -> Vc
 cout << res << " " << Vc << endl;


 //Single matrix operations :
 Mc = Mb.t();      // transpose(Ma) -> Mb (cannot transpose onto self)
 cout << Mc << endl;
 cv::Scalar t = trace(Ma); // trace(Ma) -> t.val[0] 
 cout << t.val[0] << endl; 
 double d = determinant(Ma); // det(Ma) -> d
 cout << d << endl;
 Mc = Ma.inv();         // inv(Mb) -> Mc
 invert(Ma, Mc);
 cout << Mc << endl;


 //Inhomogeneous linear system solver :
 double dm2[3][3] = { { 1, 2, 3 }, { 4, 5, 6 }, { 7, 8, 9 } };
 Mat A(3, 3, CV_64FC1, dm2);
 Mat x(3, 1, CV_64FC1);
 double vvb[] = { 14, 32, 52 };
 Mat b(3, 1, CV_64FC1, vvb);
 cv::solve(A, b, x, DECOMP_SVD); //// solve (Ax=b) for x
 cout << x << endl;


 //Eigen analysis(of a symmetric matrix) :
 float f11[] = { 1, 0.446, -0.56, 0.446, 1, -0.239, -0.56, 0.239, 1 };
 Mat data(3, 3, CV_32F, f11);
 Mat value, vector;
 eigen(data, value, vector);
 cout << "Eigenvalues" << value << endl;
 cout << "Eigenvectors" << endl;
 cout << vector << endl;


 //Singular value decomposition :
 Mat w, u, v;
 SVDecomp(data, w, u, v); // A = U W V^T
 //The flags cause U and V to be returned transposed(does not work well without the transpose flags).
 cout << w << endl;
 cout << u << endl;
 cout << v << endl;
...


refer to this posting
optical flow and matching using gpu
http://feelmare.blogspot.kr/2014/07/opencv-study-opticalflow-gpu-feature.html
orb feature and matching using gpu
http://feelmare.blogspot.kr/2014/07/opencv-study-orb-gpu-feature-extraction.html
surf feature and matching using gpu
http://feelmare.blogspot.kr/2014/07/opencv-study-surf-gpu-and-matching.html

(Opencv Study) Orb gpu feature extraction and Matching (ORB_GPU, BruteForceMatcher_GPU example source code)

This is example source cod of ORB_GPU feature detection and matching.
ORB feature is known extraction speed is faster than surf and sift.
By the way, in my test case, speed time is not so fast.
But surf and sift is nofree algorithm. orb is free to use in commercial project.

This figure is matching result of orb example.
Note, this is gpu version result.


 

The example source code is here.
Especially, ORB is using Hamming matching method. L1 and L2 cann't use.

#include < stdio.h>
#include < iostream>

#include < opencv2\opencv.hpp>
#include < opencv2/core/core.hpp>
#include < opencv2/highgui/highgui.hpp>
//#include < opencv2/video/background_segm.hpp>
#include < opencv2\gpu\gpu.hpp>
#include < opencv2\stitching\detail\matchers.hpp >  
//#include < opencv2\nonfree\features2d.hpp >    


#ifdef _DEBUG        
#pragma comment(lib, "opencv_core247d.lib")
#pragma comment(lib, "opencv_gpu247d.lib")
#pragma comment(lib, "opencv_features2d247d.lib")
#pragma comment(lib, "opencv_highgui247d.lib")
#pragma comment(lib, "opencv_nonfree247d.lib")
#else
#pragma comment(lib, "opencv_core247.lib")
#pragma comment(lib, "opencv_gpu247.lib")
#pragma comment(lib, "opencv_features2d247.lib")
#pragma comment(lib, "opencv_highgui247.lib")
#pragma comment(lib, "opencv_nonfree247.lib");
#endif 



using namespace cv;
using namespace std;



void main()
{

 

 gpu::GpuMat img1(imread("C:\\videoSample\\Image\\Picture6.jpg", CV_LOAD_IMAGE_GRAYSCALE)); 
    gpu::GpuMat img2(imread("C:\\videoSample\\Image\\Picture7.jpg", CV_LOAD_IMAGE_GRAYSCALE)); 


 unsigned long t_AAtime=0, t_BBtime=0;
 float t_pt;
 float t_fpt;
 t_AAtime = getTickCount(); 


 
 //extractFeatures
 gpu::ORB_GPU orb(2000);
 gpu::GpuMat keypoints1GPU, keypoints2GPU; 
    gpu::GpuMat descriptors1GPU, descriptors2GPU; 

 
 orb(img1, gpu::GpuMat(), keypoints1GPU, descriptors1GPU);
 orb(img2, gpu::GpuMat(), keypoints2GPU, descriptors2GPU);

 cout << "FOUND " << keypoints1GPU.cols << " keypoints on first image" << endl; 
    cout << "FOUND " << keypoints2GPU.cols << " keypoints on second image" << endl; 

 gpu::BruteForceMatcher_GPU< Hamming > matcher;    
 vector< vector< DMatch> > matches; 
 matcher.knnMatch(descriptors1GPU, descriptors2GPU, matches, 2); 
 
 //matching
 std::vector< DMatch > good_matches;
 for(int k = 0; k < min(descriptors1GPU.rows-1,(int) matches.size()); k++) 
    {
        if((matches[k][0].distance < 0.6*(matches[k][1].distance)) && ((int) matches[k].size()<=2 && (int) matches[k].size()>0))
        {
            good_matches.push_back(matches[k][0]);
        }
    }    


 t_BBtime = getTickCount();
 t_pt = (t_BBtime - t_AAtime)/getTickFrequency();
 t_fpt = 1/t_pt;
 printf("%.4lf sec/ %.4lf fps\n",  t_pt, t_fpt );


 vector< KeyPoint> keypoints1, keypoints2;
    vector< float> descriptors1, descriptors2;
    orb.downloadKeyPoints(keypoints1GPU, keypoints1);
    orb.downloadKeyPoints(keypoints2GPU, keypoints2);
 printf("%d %d\n", keypoints1.size(), keypoints2.size() );

 
 Mat img_matches; 
 Mat img11, img22;
 img1.download(img11);
 img2.download(img22);
 Mat outImg;

    drawMatches(img11, keypoints1, img22, keypoints2, good_matches, img_matches);
 //drawKeypoints(img11, kp1, outImg);

 namedWindow("matches", 0);
    imshow("matches", img_matches);

    waitKey(0);
}


//
refer to this posting
optical flow and matching using gpu
http://feelmare.blogspot.kr/2014/07/opencv-study-opticalflow-gpu-feature.html
orb feature and matching using gpu
http://feelmare.blogspot.kr/2014/07/opencv-study-orb-gpu-feature-extraction.html
surf feature and matching using gpu
http://feelmare.blogspot.kr/2014/07/opencv-study-surf-gpu-and-matching.html

7/27/2014

(OpenCV Study) Surf GPU and Matching (SURF_GPU, BruteForceMatcher_GPU example source code)

This is example source code of Matching using surf and bruteForceMathing of gpu version.
I think this simple example source code is useful to your gpu mode feature matching project.

This is source image.
The RC car is my favorite machine.


 
 
The figure is result of surf matching.



Processing time is 0.4028second and 2.4828 fps.
Image size is 1920x1080.


#include < stdio.h>
#include < iostream>

#include < opencv2\opencv.hpp>
#include < opencv2/core/core.hpp>
#include < opencv2/highgui/highgui.hpp>
#include < opencv2\gpu\gpu.hpp>
#include < opencv2\stitching\detail\matchers.hpp >  


#ifdef _DEBUG        
#pragma comment(lib, "opencv_core247d.lib")
#pragma comment(lib, "opencv_gpu247d.lib")
#pragma comment(lib, "opencv_features2d247d.lib")
#pragma comment(lib, "opencv_highgui247d.lib")
#pragma comment(lib, "opencv_nonfree247d.lib")
#else
#pragma comment(lib, "opencv_core247.lib")
#pragma comment(lib, "opencv_gpu247.lib")
#pragma comment(lib, "opencv_features2d247.lib")
#pragma comment(lib, "opencv_highgui247.lib")
#pragma comment(lib, "opencv_nonfree247.lib")
#endif 


using namespace cv;
using namespace std;

void main()
{
gpu::GpuMat img1(imread("C:\\videoSample\\Image\\Picture6.jpg", CV_LOAD_IMAGE_GRAYSCALE)); 
    gpu::GpuMat img2(imread("C:\\videoSample\\Image\\Picture7.jpg", CV_LOAD_IMAGE_GRAYSCALE)); 

 
 /////////////////////////////////////////////////////////////////////////////////////////
 unsigned long t_AAtime=0, t_BBtime=0;
 float t_pt;
 float t_fpt;
 t_AAtime = getTickCount(); 
 /////////////////////////////////////////////////////////////////////////////////////////

    gpu::SURF_GPU surf(400);
    // detecting keypoints & computing descriptors 
    gpu::GpuMat keypoints1GPU, keypoints2GPU; 
    gpu::GpuMat descriptors1GPU, descriptors2GPU; 
    surf(img1, gpu::GpuMat(), keypoints1GPU, descriptors1GPU); 
    surf(img2, gpu::GpuMat(), keypoints2GPU, descriptors2GPU); 
    
    cout << "FOUND " << keypoints1GPU.cols << " keypoints on first image" << endl; 
    cout << "FOUND " << keypoints2GPU.cols << " keypoints on second image" << endl; 

    // matching descriptors 
    gpu::BruteForceMatcher_GPU< L2< float> > matcher;    
 vector< vector< DMatch> > matches; 
 matcher.knnMatch(descriptors1GPU, descriptors2GPU, matches, 2); 
    
    // downloading results  Gpu -> Cpu
    vector< KeyPoint> keypoints1, keypoints2; 
    vector< float> descriptors1, descriptors2; 
    surf.downloadKeypoints(keypoints1GPU, keypoints1);
    surf.downloadKeypoints(keypoints2GPU, keypoints2);
    //surf.downloadDescriptors(descriptors1GPU, descriptors1); 
    //surf.downloadDescriptors(descriptors2GPU, descriptors2);

 vector< KeyPoint> matchingKey1, matchingKey2;
 std::vector< DMatch > good_matches;
 for(int k = 0; k < min(descriptors1GPU.rows-1,(int) matches.size()); k++) 
    {
        if((matches[k][0].distance < 0.6*(matches[k][1].distance)) && ((int) matches[k].size()<=2 && (int) matches[k].size()>0))
        {
            good_matches.push_back(matches[k][0]);

        }
    }
 


 
 t_BBtime = getTickCount();
 t_pt = (t_BBtime - t_AAtime)/getTickFrequency();
 t_fpt = 1/t_pt;
 printf("feature extraction = %.4lf / %.4lf \n",  t_pt, t_fpt );



 
 
 
    // drawing the results 
    Mat img_matches; 
 Mat img11, img22;
 img1.download(img11);
 img2.download(img22);
 
 //drawMatches(img11, matchingKey1, img22, matchingKey2, good_matches, img_matches); 
    drawMatches(img11, keypoints1, img22, keypoints2, good_matches, img_matches); 

 //drawKeypoints(img11, keypoints1, img_matches);
 

    namedWindow("matches", 0); 
    imshow("matches", img_matches); 
    waitKey(0); 
}




refer to this posting
optical flow and matching using gpu
http://feelmare.blogspot.kr/2014/07/opencv-study-opticalflow-gpu-feature.html
orb feature and matching using gpu
http://feelmare.blogspot.kr/2014/07/opencv-study-orb-gpu-feature-extraction.html
surf feature and matching using gpu
http://feelmare.blogspot.kr/2014/07/opencv-study-surf-gpu-and-matching.html

12/17/2013

Finding largest subset images that is only adjacent(subsequnce) images, (OpenCV, SurfFeaturesFinder, BestOf2NearestMatcher, leaveBiggestComponent funcions example souce code)

The souce code flow is like that...

1.
find features in each images using SurfFeaturesFinder function.
Features value is contained in the ImageFeatures structure.

2.
Matching features.
Matcher(features, pairwise_matches, matching_mask)
in the source code, features is vector.
So the Matcher function get matcing value of each pair images.

3.
leave biggest component,
Using conf_threshold, the function leaves largest correlation images.

Input
Input image is 6 images.
4 images are sequence images, 2 images is another sequence images.

Output
The souce code gives the result that is index of subset images of 4 images component.



////
#include < stdio.h >  
#include < opencv2\opencv.hpp >  
#include < opencv2\features2d\features2d.hpp >
#include < opencv2\nonfree\features2d.hpp >
#include < opencv2\stitching\detail\matchers.hpp >
#include < opencv2\stitching\stitcher.hpp >


#ifdef _DEBUG  
#pragma comment(lib, "opencv_core247d.lib")   
//#pragma comment(lib, "opencv_imgproc247d.lib")   //MAT processing  
//#pragma comment(lib, "opencv_objdetect247d.lib")   
//#pragma comment(lib, "opencv_gpu247d.lib")  
#pragma comment(lib, "opencv_features2d247d.lib")  
#pragma comment(lib, "opencv_highgui247d.lib")  
//#pragma comment(lib, "opencv_ml247d.lib")
#pragma comment(lib, "opencv_stitching247d.lib");
#pragma comment(lib, "opencv_nonfree247d.lib");

#else  
#pragma comment(lib, "opencv_core247.lib")  
//#pragma comment(lib, "opencv_imgproc247.lib")  
//#pragma comment(lib, "opencv_objdetect247.lib")  
//#pragma comment(lib, "opencv_gpu247.lib")  
#pragma comment(lib, "opencv_features2d247.lib")  
#pragma comment(lib, "opencv_highgui247.lib")  
//#pragma comment(lib, "opencv_ml247.lib")  
#pragma comment(lib, "opencv_stitching247.lib");
#pragma comment(lib, "opencv_nonfree247.lib");
#endif  

using namespace cv;  
using namespace std;


void main()  
{
 vector< Mat > vImg;
 Mat rImg;

 vImg.push_back( imread("./m7.jpg") );
 vImg.push_back( imread("./B1.jpg") );
 vImg.push_back( imread("./m9.jpg") );
 vImg.push_back( imread("./m6.jpg") );
 vImg.push_back( imread("./B2.jpg") );
 vImg.push_back( imread("./m8.jpg") );
 

 //feature extract
 detail::SurfFeaturesFinder FeatureFinder;
 vector< detail::ImageFeatures> features;
 
 for(int i=0; i< vImg.size(); ++i)
 {  
  detail::ImageFeatures F;
  FeatureFinder(vImg[i], F);  
  features.push_back(F);
  features[i].img_idx = i;
  printf("Keypoint of [%d] - %d points \n", i, features[i].keypoints.size() );
 }
 FeatureFinder.collectGarbage();

 //match
 vector<  int> indices_;
 double conf_thresh_ = 1.0;
 Mat matching_mask;
 vector<  detail::MatchesInfo> pairwise_matches;
 detail::BestOf2NearestMatcher Matcher;
 Matcher(features, pairwise_matches, matching_mask);
 Matcher.collectGarbage();

 printf("\nBiggest subset is ...\n");
 // Leave only images we are sure are from the same panorama 
 indices_ = detail::leaveBiggestComponent(features, pairwise_matches, (float)conf_thresh_);
 Matcher.collectGarbage();

 for (size_t i = 0; i <  indices_.size(); ++i)
    {
  printf("%d \n", indices_[i] );
 }
 

}

////