Celebrandil / CudaSift

A CUDA implementation of SIFT for NVidia GPUs (1.2 ms on a GTX 1060)
MIT License
860 stars 285 forks source link

Hello, Celebrandil, last time you told me that I need ubuntu, I have already installed it, and it is compiled, but my result is not the same as yours, and there is no match between the two images. #54

Closed yangninghua closed 5 years ago

yangninghua commented 5 years ago

Hello, Celebrandil, last time you told me that I need ubuntu, I have already installed it, and it is compiled, but my result is not the same as yours, and there is no match between the two images. image image

yangninghua commented 5 years ago

The match does not appear in pairs, but an image appears separately. Is my use error? I ran ./cudasift 0 1

yangninghua commented 5 years ago

image

yangninghua commented 5 years ago
//********************************************************//
// CUDA SIFT extractor by Marten Björkman aka Celebrandil //
//              celle @ csc.kth.se                       //
//********************************************************//  

#include <iostream>  
#include <cmath>
#include <iomanip>
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>

#include "cudaImage.h"
#include "cudaSift.h"

int ImproveHomography(SiftData &data, float *homography, int numLoops, float minScore, float maxAmbiguity, float thresh);
void PrintMatchData(SiftData &siftData1, SiftData &siftData2, CudaImage &img);
void MatchAll(SiftData &siftData1, SiftData &siftData2, float *homography);

double ScaleUp(CudaImage &res, CudaImage &src);
void showCorrespondence(SiftData &siftData1, SiftData &siftData2, cv::Mat limg_0, cv::Mat rimg_0);

///////////////////////////////////////////////////////////////////////////////
// Main program
///////////////////////////////////////////////////////////////////////////////
int main(int argc, char **argv) 
{    
  int devNum = 0, imgSet = 0;
  if (argc>1)
    devNum = std::atoi(argv[1]);
  if (argc>2)
    imgSet = std::atoi(argv[2]);

  // Read images using OpenCV
  cv::Mat limg, rimg;
  if (imgSet) {
    cv::imread("data/left.pgm", 0).convertTo(limg, CV_32FC1);
    cv::imread("data/righ.pgm", 0).convertTo(rimg, CV_32FC1);
  } else {
    cv::imread("data/img1.png", 0).convertTo(limg, CV_32FC1);
    cv::imread("data/img2.png", 0).convertTo(rimg, CV_32FC1);
  }
  //cv::flip(limg, rimg, -1);
  unsigned int w = limg.cols;
  unsigned int h = limg.rows;
  std::cout << "Image size = (" << w << "," << h << ")" << std::endl;

  // Initial Cuda images and download images to device
  std::cout << "Initializing data..." << std::endl;
  InitCuda(devNum); 
  CudaImage img1, img2;
  img1.Allocate(w, h, iAlignUp(w, 128), false, NULL, (float*)limg.data);
  img2.Allocate(w, h, iAlignUp(w, 128), false, NULL, (float*)rimg.data);
  img1.Download();
  img2.Download(); 

  // Extract Sift features from images
  SiftData siftData1, siftData2;
  float initBlur = 1.0f;
  float thresh = (imgSet ? 4.5f : 3.0f);
  InitSiftData(siftData1, 32768, true, true); 
  InitSiftData(siftData2, 32768, true, true);

  // A bit of benchmarking 
  //for (int thresh1=1.00f;thresh1<=4.01f;thresh1+=0.50f) {
  float *memoryTmp = AllocSiftTempMemory(w, h, 5, false);
    for (int i=0;i<1000;i++) {
      ExtractSift(siftData1, img1, 5, initBlur, thresh, 0.0f, false, memoryTmp);
      ExtractSift(siftData2, img2, 5, initBlur, thresh, 0.0f, false, memoryTmp);
    }
    FreeSiftTempMemory(memoryTmp);

    // Match Sift features and find a homography
    for (int i=0;i<1;i++)
      MatchSiftData(siftData1, siftData2);
    float homography[9];
    int numMatches;
    FindHomography(siftData1, homography, &numMatches, 10000, 0.00f, 0.80f, 5.0);
    int numFit = ImproveHomography(siftData1, homography, 5, 0.00f, 0.80f, 3.0);

    std::cout << "Number of original features: " <<  siftData1.numPts << " " << siftData2.numPts << std::endl;
    std::cout << "Number of matching features: " << numFit << " " << numMatches << " " << 100.0f*numFit/std::min(siftData1.numPts, siftData2.numPts) << "% " << initBlur << " " << thresh << std::endl;
    //}

  // Print out and store summary data
  //PrintMatchData(siftData1, siftData2, img1);
  //cv::imwrite("data/ynh1.pgm", limg);
  //cv::imwrite("data/ynh2.pgm", rimg);
  cv::Mat limg_0 = limg.clone();
  cv::Mat rimg_0 = rimg.clone();
  cv::cvtColor(limg_0,limg_0,CV_GRAY2BGR);
  cv::cvtColor(rimg_0,rimg_0,CV_GRAY2BGR);
  showCorrespondence(siftData1, siftData2, limg_0, rimg_0);

  //MatchAll(siftData1, siftData2, homography);

  // Free Sift data from device
  FreeSiftData(siftData1);
  FreeSiftData(siftData2);
}

void showCorrespondence(SiftData &siftData1, SiftData &siftData2, cv::Mat limg_0, cv::Mat rimg_0)
{
    int numPts = siftData1.numPts;
    SiftPoint *sift1 = siftData1.h_data;
    SiftPoint *sift2 = siftData2.h_data;

    int w = limg_0.size().width;
    int h = limg_0.size().height;

    cv::resize(rimg_0, rimg_0, cv::Size(w, h));

    cv::Mat img_m = cv::Mat::zeros(h , 2*w,CV_8UC3);

    limg_0.copyTo(img_m(cv::Rect(0,0,w,h)));
    rimg_0.copyTo(img_m(cv::Rect(w,0,w,h)));

    std::cout << sift1[1].xpos << ", " << sift1[1].ypos << std::endl;
    for (int j = 0; j < numPts; j++)
    {
        int k = sift1[j].match;
        if (sift1[j].match_error < 5)
        {
            cv::circle(img_m, cv::Point(sift1[j].xpos, sift1[j].ypos),2,cv::Scalar(60, 20, 220),2);
            cv::circle(img_m, cv::Point(sift1[j].match_xpos + w, sift1[j].match_ypos), 2, cv::Scalar(255, 0, 0),2);
            std::cout << sift1[j].match_xpos << ", " << sift1[j].match_ypos << std::endl;
            cv::line(img_m,cv::Point(sift1[j].xpos, sift1[j].ypos),cv::Point(sift1[j].match_xpos + w, sift1[j].match_ypos),cv::Scalar(0,255,0),1);
        }
    }

    cv::namedWindow("Result");
    cv::resizeWindow("Result",cv::Size(600,300));
    cv::imshow("Result",img_m);
    cv::waitKey();
}

void MatchAll(SiftData &siftData1, SiftData &siftData2, float *homography)
{
#ifdef MANAGEDMEM
  SiftPoint *sift1 = siftData1.m_data;
  SiftPoint *sift2 = siftData2.m_data;
#else
  SiftPoint *sift1 = siftData1.h_data;
  SiftPoint *sift2 = siftData2.h_data;
#endif
  int numPts1 = siftData1.numPts;
  int numPts2 = siftData2.numPts;
  int numFound = 0;
#if 1
  homography[0] = homography[4] = -1.0f;
  homography[1] = homography[3] = homography[6] = homography[7] = 0.0f;
  homography[2] = 1279.0f;
  homography[5] = 959.0f;
#endif
  for (int i=0;i<numPts1;i++) {
    float *data1 = sift1[i].data;
    std::cout << i << ":" << sift1[i].scale << ":" << (int)sift1[i].orientation << " " << sift1[i].xpos << " " << sift1[i].ypos << std::endl;
    bool found = false;
    for (int j=0;j<numPts2;j++) {
      float *data2 = sift2[j].data;
      float sum = 0.0f;
      for (int k=0;k<128;k++) 
    sum += data1[k]*data2[k];    
      float den = homography[6]*sift1[i].xpos + homography[7]*sift1[i].ypos + homography[8];
      float dx = (homography[0]*sift1[i].xpos + homography[1]*sift1[i].ypos + homography[2]) / den - sift2[j].xpos;
      float dy = (homography[3]*sift1[i].xpos + homography[4]*sift1[i].ypos + homography[5]) / den - sift2[j].ypos;
      float err = dx*dx + dy*dy;
      if (err<100.0f) // 100.0
    found = true;
      if (err<100.0f || j==sift1[i].match) { // 100.0
    if (j==sift1[i].match && err<100.0f)
      std::cout << " *";
    else if (j==sift1[i].match) 
      std::cout << " -";
    else if (err<100.0f)
      std::cout << " +";
    else
      std::cout << "  ";
    std::cout << j << ":" << sum << ":" << (int)sqrt(err) << ":" << sift2[j].scale << ":" << (int)sift2[j].orientation << " " << sift2[j].xpos << " " << sift2[j].ypos << " " << (int)dx << " " << (int)dy << std::endl;
      }
    }
    std::cout << std::endl;
    if (found)
      numFound++;
  }
  std::cout << "Number of finds: " << numFound << " / " << numPts1 << std::endl;
  std::cout << homography[0] << " " << homography[1] << " " << homography[2] << std::endl;//%%%
  std::cout << homography[3] << " " << homography[4] << " " << homography[5] << std::endl;//%%%
  std::cout << homography[6] << " " << homography[7] << " " << homography[8] << std::endl;//%%%
}

void PrintMatchData(SiftData &siftData1, SiftData &siftData2, CudaImage &img)
{
  int numPts = siftData1.numPts;
#ifdef MANAGEDMEM
  SiftPoint *sift1 = siftData1.m_data;
  SiftPoint *sift2 = siftData2.m_data;
#else
  SiftPoint *sift1 = siftData1.h_data;
  SiftPoint *sift2 = siftData2.h_data;
#endif
  float *h_img = img.h_data;
  int w = img.width;
  int h = img.height;
  std::cout << std::setprecision(3);
  for (int j=0;j<numPts;j++) { 
    int k = sift1[j].match;
    if (sift1[j].match_error<5) {
      float dx = sift2[k].xpos - sift1[j].xpos;
      float dy = sift2[k].ypos - sift1[j].ypos;
#if 0
      if (false && sift1[j].xpos>550 && sift1[j].xpos<600) {
    std::cout << "pos1=(" << (int)sift1[j].xpos << "," << (int)sift1[j].ypos << ") ";
    std::cout << j << ": " << "score=" << sift1[j].score << "  ambiguity=" << sift1[j].ambiguity << "  match=" << k << "  ";
    std::cout << "scale=" << sift1[j].scale << "  ";
    std::cout << "error=" << (int)sift1[j].match_error << "  ";
    std::cout << "orient=" << (int)sift1[j].orientation << "," << (int)sift2[k].orientation << "  ";
    std::cout << " delta=(" << (int)dx << "," << (int)dy << ")" << std::endl;
      }
#endif
#if 1
      int len = (int)(fabs(dx)>fabs(dy) ? fabs(dx) : fabs(dy));
      for (int l=0;l<len;l++) {
    int x = (int)(sift1[j].xpos + dx*l/len);
    int y = (int)(sift1[j].ypos + dy*l/len);
    h_img[y*w+x] = 255.0f;
      }
#endif
    }
    int x = (int)(sift1[j].xpos+0.5);
    int y = (int)(sift1[j].ypos+0.5);
    int s = std::min(x, std::min(y, std::min(w-x-2, std::min(h-y-2, (int)(1.41*sift1[j].scale)))));
    int p = y*w + x;
    p += (w+1);
    for (int k=0;k<s;k++) 
      h_img[p-k] = h_img[p+k] = h_img[p-k*w] = h_img[p+k*w] = 0.0f;
    p -= (w+1);
    for (int k=0;k<s;k++) 
      h_img[p-k] = h_img[p+k] = h_img[p-k*w] =h_img[p+k*w] = 255.0f;
  }
  std::cout << std::setprecision(6);
}
bigdimboom commented 5 years ago

same issue, no matching found. How did you fix it? image

yangninghua commented 5 years ago

same issue, no matching found. How did you fix it? image

Hello, I posted my code modification above.