Skip to content

Instantly share code, notes, and snippets.

@yu4u
Created June 18, 2013 14:47
Show Gist options
  • Select an option

  • Save yu4u/5805973 to your computer and use it in GitHub Desktop.

Select an option

Save yu4u/5805973 to your computer and use it in GitHub Desktop.
Extract a single SIFT feature vector (global SIFT) from an entire image.
void extractGSIFT(const cv::Mat& src, std::vector<float>& feature)
{
const int W = 200;
const int H = 200;
const int NBP = 4;
const int NBO = 8;
const bool USEW = true;
cv::Mat gray;
cv::Mat img;
cv::cvtColor(src, gray, CV_RGB2GRAY);
cv::resize(gray, img, cv::Size(W, H));
cv::blur(img, img, cv::Size(5, 5));
feature.resize(NBP * NBP * NBO, 0.0f);
for (int y = 1; y < H - 1; ++y) {
for (int x = 1; x < W - 1; ++x) {
const float dx = 0.5f * (img.at<uchar>(y, x + 1) - img.at<uchar>(y, x - 1));
const float dy = 0.5f * (img.at<uchar>(y + 1, x) - img.at<uchar>(y - 1, x));
const float m = std::sqrt(dx * dx + dy * dy);
const float o = std::fmod(std::atan2(dy, dx) + 2 * (float)M_PI, 2 * (float)M_PI);
const float nx = (float)x * NBP / W;
const float ny = (float)y * NBP / H;
const float nt = o * NBO / (2 * (float)M_PI);
const int binx = (int)std::floor(nx - 0.5f);
const int biny = (int)std::floor(ny - 0.5f);
const int bint = (int)std::floor(nt);
const float rbinx = nx - (binx + 0.5f);
const float rbiny = ny - (biny + 0.5f);
const float rbint = nt - bint;
const float wsigma = 0.5f * NBP;
float win = 1.0f;
if (USEW) {
float a = (nx - 0.5f * NBP) * (nx - 0.5f * NBP) + (ny - 0.5f * NBP) * (ny - 0.5f * NBP);
win = std::exp(- a / (2.0f * wsigma * wsigma));
}
for (int dbinx = 0; dbinx < 2; ++dbinx) {
for (int dbiny = 0; dbiny < 2; ++dbiny) {
for (int dbint = 0; dbint < 2; ++dbint) {
if (binx + dbinx >= 0 &&
binx + dbinx < NBP &&
biny + dbiny >= 0 &&
biny + dbiny < NBP)
{
const float weight = win * m * std::abs(1.0f - dbinx - rbinx) * std::abs(1.0f - dbiny - rbiny) * std::abs(1.0f - dbint - rbint);
feature[(biny + dbiny) * NBP * NBO + (binx + dbinx) * NBO + ((bint + dbint) % NBO)] += weight;
}
}
}
}
}
}
const float sum = std::accumulate(feature.begin(), feature.end(), 0.0f);
for (int i = 0; i < feature.size(); ++i) {
feature[i] = std::sqrt(feature[i] / sum);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment