应用:连续的图像移动或图像拼接场景中,确定图像中某一对象的位置。
在x方向和y方向都有最大梯度变化的像素点,衡量这个变化的计算式如下,为xx,xy,yx,yy四个方向的梯度sum值组成的2×2矩阵:
a)在实际过程中,会在计算梯度时,乘以一个对应位置的权重 w(x, y),u,v为沿着对应方向移动的距离。
b)在经过转换后得到新的E(u, v)式子:
其中:
c)最后解出矩阵特征值和,再根据下图和获取的和来判断出该像素点是否为角点。
shi-tomasi角点检测:求min(, ) 所处区域,从而确定角点。
harris角点检测:
void cv::cornerHarris ( InputArray src,
OutputArray dst,
int blockSize,
int ksize,
double k,
int borderType = BORDER_DEFAULT
)
blockSize ——计算角点时,覆盖像素点的窗口大小,即上文中的u、v值
ksize——Sobel算子应用的卷积核大小
k ——Harris detector free parameter. See the formula below.
角点检测通用API,可以配置选用不同的角点检测方法。
void cv::goodFeaturesToTrack ( InputArray image,
OutputArray corners,
int maxCorners,
double qualityLevel,
double minDistance,
InputArray mask = noArray(),
int blockSize = 3,
bool useHarrisDetector = false,
double k = 0.04
)
image ——输入:单通道图像,即灰度图。
corners——输出角点数组:vector
maxCorners ——返回的最大角点数量。 If there are more corners than are found, the strongest of them is returned. maxCorners <= 0 implies that no limit on the maximum is set and all detected corners are returned.
qualityLevel——Parameter characterizing the minimal accepted quality of image corners. The parameter value is multiplied by the best corner quality measure, which is the minimal eigenvalue (see cornerMinEigenVal ) or the Harris function response (see cornerHarris ). The corners with the quality measure less than the product are rejected. For example, if the best corner has the quality measure = 1500, and the qualityLevel=0.01 , then all the corners with the quality measure less than 15 are rejected.
minDistance——两个角点间最小的Euclidean距离.
blockSize——Size of an average block for computing a derivative covariation matrix over each pixel neighborhood. See cornerEigenValsAndVecs .
useHarrisDetector ——bool型,是否使用harris角点检测
k ——Free parameter of the Harris detector.
harris:
void QuickDemo::harris(Mat& image)
{
//灰度图
Mat gray;
cvtColor(image, gray, COLOR_BGR2GRAY);
//harris检测
Mat dst;
cornerHarris(gray, dst, 2, 3, 0.04);
//归一化
Mat dst_norm = Mat::zeros(dst.size(), dst.type());
normalize(dst, dst_norm, 0, 255, NORM_MINMAX, -1, Mat());
//绝对值化
convertScaleAbs(dst_norm, dst_norm);
//绘制角点
RNG rng(12345);
for (int row = 0; row < image.rows; ++row) {
for (int col = 0; col < image.cols; ++col) {
int rsp = dst_norm.at(row, col);//取出对应像素坐标的检测值
//限制
if (rsp > 150) {
int b = rng.uniform(0, 255);
int g = rng.uniform(0, 255);
int r = rng.uniform(0, 255);
circle(image, Point(col, row), 3, Scalar(b, g, r), 1, 8);
}
}
}
namedWindow("result", WINDOW_FREERATIO);
imshow("result", image);
}
shi-tomasi:
void QuickDemo::shi_tomasi(Mat& image)
{
//灰度图
Mat gray;
cvtColor(image, gray, COLOR_BGR2GRAY);
vector corners;
goodFeaturesToTrack(gray, corners, 200, 0.01, 3, Mat(), 3, false);
//绘制角点
RNG rng(12345);
for (int i = 0; i < corners.size(); ++i) {
int b = rng.uniform(0, 255);
int g = rng.uniform(0, 255);
int r = rng.uniform(0, 255);
circle(image, corners[i], 3, Scalar(b, g, r), 1, 8);
}
namedWindow("result", WINDOW_FREERATIO);
imshow("result", image);
}