opencv关键接口函数:
//Calculates the minimal eigenvalue of gradient matrices for corner detection.
The function is similar to cornerEigenValsAndVecs but it calculates and stores only the minimal
eigenvalue of the covariance matrix of derivatives, that is, min(λ1,λ2) in terms of the formulae in
the cornerEigenValsAndVecs description.
void cv::cornerMinEigenVal ( InputArray src,
OutputArray dst,
int blockSize,
int ksize = 3,
int borderType = BORDER_DEFAULT
)
//finds global minimum and maximum array elements and returns their values and their locations
void cv::minMaxLoc ( InputArray src,
double * minVal,
double * maxVal = 0,
Point * minLoc = 0,
Point * maxLoc = 0,
InputArray mask = noArray()
)
//minVal
//maxVal
//minLoc
//maxLoc
//InputArray
函数描述:
这里以单副图像为例,通过计算灰度图像每一个像素点自相关矩阵的特征值,通过设置阈值去除低于该阈值的像素点。阈值公式如下:
其中,是图像中像素点 的特征值,0.001为实验中确定的值。程序运行结果即为密集采样后的效果图。
头文件:
//
// Created by wang on 2021/5/13.
//
#ifndef DENSESAMPLE_EXAMPLE_00_DENSESAMPLE_H
#define DENSESAMPLE_EXAMPLE_00_DENSESAMPLE_H
#include "string"
#include "opencv2/opencv.hpp"
class DenseSample
{
public:
DenseSample(const std::string& imgDIr,double quality,int minDistance);
~DenseSample();
void Run();
void KeyPointsShow();
private:
std::string m_inDir;
double m_quality;
int m_minDistance;
cv::Mat m_pic;
std::vector<cv::Point2f> m_points;
bool openPic();
};
#endif //DENSESAMPLE_EXAMPLE_00_DENSESAMPLE_H
源文件:
//
// Created by wang on 2021/5/13.
//
#include "DenseSample.h"
DenseSample::DenseSample(const std::string &imgDIr, double quality, int minDistance)
{
m_inDir=imgDIr;
m_quality=quality;
m_minDistance=minDistance;
}
DenseSample::~DenseSample()
{
}
bool DenseSample::openPic()
{
if(m_inDir.empty())
{
std::cerr<<"Image path is empty!"<<std::endl;
return false;
}
return true;
}
void DenseSample::Run()
{
if(openPic())
{
m_pic=cv::imread(m_inDir,cv::IMREAD_COLOR);
}
cv::imshow("Init image",m_pic);
cv::Mat gray;
cv::cvtColor(m_pic,gray,cv::COLOR_BGR2GRAY);
int width=gray.cols/m_minDistance;
int height=gray.rows/m_minDistance;
cv::Mat eig;
cv::cornerMinEigenVal(gray,eig,3,3);
double maxVal=0;
cv::minMaxLoc(eig,0,&maxVal);
const double thresh=maxVal*m_quality;
std::vector<int> counters(width*height);
int xMax=m_minDistance*width;
int yMax=m_minDistance*height;
for(size_t i=0;i<m_points.size();i++)
{
cv::Point2f point=m_points[i];
int x=cvFloor(point.x);
int y=cvFloor(point.y);
if(x>=xMax || y>=yMax)
{
continue;
}
x/=m_minDistance;
y/=m_minDistance;
counters[y*width+x]++;
}
m_points.clear();
int index=0;
int offset=m_minDistance/2;
for(size_t i=0;i<height;i++)
{
for(size_t j=0;j<width;j++)
{
if(counters[index]>0)
{
continue;
}
int x=j*m_minDistance+offset;
int y=i*m_minDistance+offset;
if(eig.at<float>(y,x)>thresh)
{
m_points.push_back(cv::Point2f(float(x),float(y)));
}
}
}
}
void DenseSample::KeyPointsShow()
{
for(size_t i=0;i<m_points.size();i++)
{
cv::circle(m_pic,m_points[i],3,cv::Scalar(255,0,0),1);
}
cv::imshow("DenseSample",m_pic);
cv::waitKey(0);
}
效果图:
IDT算法网址:
http://lear.inrialpes.fr/people/wang/improved_trajectories
参考:
https://blog.csdn.net/wzmsltw/article/details/53023363 该博客对稠密轨迹算法进行了整体的解读