在学习图像金字塔代码之前,需要先看角点检测的的代码,因为在图像金字塔中,检测的点用的就是角点
1.角点检测
1.1角点检测代码
void cv::goodFeaturesToTrack(
cv::InputArray image, // 输入图像(CV_8UC1 CV_32FC1)
cv::OutputArray corners, // 输出角点vector
int maxCorners, // 最大角点数目
double qualityLevel, // 质量水平系数(小于1.0的正数,一般在0.01-0.1之间)
double minDistance, // 最小距离,小于此距离的点忽略
cv::InputArray mask = noArray(), // mask=0的点忽略
int blockSize = 3, // 使用的邻域数
bool useHarrisDetector = false, // false ='Shi Tomasi metric'
double k = 0.04 // Harris角点检测时使用
);
1.2角点检测参数解析:
第一个参数是输入图像(8位或32位单通道图)。
第二个参数是检测到的所有角点,类型为vector或数组,由实际给定的参数类型而定。如果是vector,那么它应该是一个包含cv::Point2f的vector对象;如果类型是cv::Mat,那么它的每一行对应一个角点,点的x、y位置分别是两列。
第三个参数用于限定检测到的点数的最大值。
第四个参数表示检测到的角点的质量水平(通常是0.10到0.01之间的数值,不能大于1.0)。
第五个参数用于区分相邻两个角点的最小距离(小于这个距离得点将进行合并)。
第六个参数是mask,如果指定,它的维度必须和输入图像一致,且在mask值为0处不进行角点检测。
第七个参数是blockSize,表示在计算角点时参与运算的区域大小,常用值为3,但是如果图像的分辨率较高则可以考虑使用较大一点的值。
第八个参数用于指定角点检测的方法,如果是true则使用Harris角点检测,false则使用Shi Tomasi算法。
第九个参数是在使用Harris算法时使用,最好使用默认值0.04。
1.3角点检测代码实例:
cv::Mat image_color = cv::imread("house.jpg", cv::IMREAD_COLOR);
//使用灰度图像进行角点检测
cv::Mat image_gray;
cv::cvtColor(image_color, image_gray, cv::COLOR_BGR2GRAY);
//设置角点检测参数
std::vector<cv::Point2f> corners;
int max_corners = 200;
double quality_level = 0.01;
double min_distance = 3.0;
int block_size = 3;
bool use_harris = false;
double k = 0.04;
//角点检测
cv::goodFeaturesToTrack(
image_gray,
corners,
max_corners,
quality_level,
min_distance,
cv::Mat(),
block_size,
use_harris,
k);
//将检测到的角点绘制到原图上
for (int i = 0; i < corners.size(); i++)
{
cv::circle(image_color, corners[i], 1, cv::Scalar(0, 0, 255), 2, 8, 0);
}
cv::imshow("house corner", image_color);
cv::waitKey(0);
return;
2金字塔Lucas-Kanande
2.1金字塔Lucas-Kanande代码
void calcOpticallFlowPyrLK (
InputArray prevImg,
InputArray nextImg,
InputArray prevPts,
InputOutputArray nextPts,
OutputArray status,
OutputArray err,
Size winSize = Size(21,21),
int maxLevel = 3,
TermCriteria criteria = TermCriteria(TermCriteria::COUNT+TermCriteria::EPS, 30, 0.01),
int flags = 0,
double minEigThreshold = 1e-4
);
2.2金字塔Lucas-Kanande代码参数解析:
2.3金字塔Lucas-Kanande代码实例:
#include <iostream>
#include <vector>
#include <opencv2/opencv.hpp>
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
const int MAX_CORNERS = 500;
int main()
{
cv::Mat imageA = cv::imread("img00001.png", 1);
cv::Mat imageB = cv::imread("img00002.png", 1);
//使用灰度图像进行角点检测
//转灰度图像
cv::Mat imageA_gray, imageB_gray;
cv::cvtColor(imageA, imageA_gray, cv::COLOR_BGR2GRAY);
cv::cvtColor(imageB, imageB_gray, cv::COLOR_BGR2GRAY);
//设置角点检测参数
std::vector<cv::Point2f> cornersA;
int max_corners = MAX_CORNERS;
double quality_level = 0.01;
double min_distance = 5.0;
int block_size = 3;
bool use_harris = false;
double k = 0.04;
//角点检测
cv::goodFeaturesToTrack(
imageA_gray,
cornersA,
max_corners,
quality_level,
min_distance,
cv::Mat(),
block_size,
use_harris,
k);
cv::Size winSize(10, 10);
cv::TermCriteria criteria = cv::TermCriteria(
cv::TermCriteria::MAX_ITER + cv::TermCriteria::EPS,
20,
0.03);
//亚像素检测
cv::cornerSubPix(imageA_gray, cornersA, winSize, cv::Size(-1, -1), criteria);
std::vector<cv::Point2f> cornersB;
std::vector<uchar> status;
std::vector<float> err;
cv::calcOpticalFlowPyrLK(imageA_gray, imageB_gray, cornersA, cornersB, status, err, winSize, 5, criteria, 0, 0.001);
cv::Mat imageC = imageB.clone();
for( int i = 0; i< cornersA.size(); i++ )
{
if(status[i] == '0') continue;
cv::Point p0 = cv::Point(cvRound(cornersA[i].x), cvRound(cornersA[i].y ));
cv::Point p1 = cv::Point(cvRound(cornersB[i].x), cvRound( cornersB[i].y));
line( imageC, p0, p1, cv::Scalar(0,0,255), 1, CV_AA);
}
cv::imshow("ImageA",imageA);
cv::imshow("ImageB",imageB);
cv::imshow("LKpyr_OpticalFlow",imageC);
cv::waitKey(0);
return 0;
}