DoG具体想明白的话可以点击链接:https://blog.csdn.net/qq_32211827/article/details/72758090,本人觉得写得比较好。如有其它问题可以加文末的群。
直接上代码:
#include <iostream>
#include <fstream>
#include "opencv2/core/core.hpp"
#include "highgui.h"
#include "opencv2/imgproc/imgproc.hpp"
#include<opencv2/opencv.hpp>
using namespace cv;
using namespace std;
Mat Process(Mat& A, double sig1, double sig2, Size Ksize)
{
Mat AF, out, out1, out2;
A.convertTo(AF, CV_32FC1);
GaussianBlur(AF, out1, Ksize, sig1, 0);
GaussianBlur(AF, out2, Ksize, sig2, 0);
subtract(out1, out2, out);
return out;
}
Mat getExtrema(Mat& A, Mat& B, Mat& C, int thresh)
{
Mat block;
Mat extr = Mat::zeros(A.rows, A.cols, CV_32FC1);
double minv, maxv;
Point minLoc, maxLoc;
for (int i = 1; i < A.rows - 2; i++)
{
for (int j = 1; j < A.cols - 2; j++)
{
block.release();
block.push_back(A(Range(i - 1, i + 2), Range(j - 1, j + 2)));
block.push_back(B(Range(i - 1, i + 2), Range(j - 1, j + 2)));
block.push_back(C(Range(i - 1, i + 2), Range(j - 1, j + 2)));
minMaxLoc(block, &minv, &maxv, &minLoc, &maxLoc);
if ((maxLoc.x == 1 && maxLoc.y == 4) && maxv > (double)thresh)
extr.at<float>(i, j) = 1;
if ((minLoc.x == 1 && minLoc.y == 4) && minv < (double)(-thresh))
extr.at<float>(i, j) = -1;
}
}
return extr;
}
void drawExtrema(Mat& img, Mat& extr)
{
Point center;
int r = 2;
for (int i = 0; i < img.rows; i++)
{
for (int j = 0; j < img.cols; j++)
{
if (extr.at<float>(i, j) == -1)
{
center = Point(j, i);
circle(img, center, r, Scalar(0, 255, 0));
}
if (extr.at<float>(i, j) == 1)
{
center = Point(j, i);
circle(img, center, r, Scalar(0, 0, 255));
}
}
}
namedWindow("DoG");
imshow("DoG", img);
waitKey(0);
}
int main(int argc, char** argv)
{
char file_name[] = "D:\\myProject\\my3DCV\\vs2019\\workspace\\Project1\\images\\kxm1.jpg";
Mat img = imread(file_name, 0);
Mat A, B, C, a;
int threshold = 3;
A = Process(img, 0.3, 0.4, Size(5, 5));
B = Process(img, 0.6, 0.7, Size(5, 5));
C = Process(img, 0.7, 0.8, Size(5, 5));
namedWindow("A");
imshow("A", A);
namedWindow("B");
imshow("B", B);
namedWindow("C");
imshow("C", C);
a = getExtrema(A, B, C, threshold);
//const char* filename = "output.txt";
//writeMatToFile(B, filename);
Mat imgB = imread(file_name);
drawExtrema(imgB, a);
return 0;
}
其中A,B,C就是通过DoG得到的结果。
结果:
A
B
C
关键点检测结果,其中红色为极大值,绿色为极小值:
本博文只发布代码,为了未来好翻阅查询之用,有问题可以加群 903635982