在图像处理中有时不需要使用物体所有
像素点
,例
如二维码定位、计算二
维码尺寸时只需要使用二维码的4个顶点,
因此有时我们需要从图像中提取能够表示图像特性或者局部特性的像
素点
,这些像素点称为角点或者特征点,使用特征点可以极大地减少数据量,
提高计算速度.特征点
广泛
应用在图像处理的各个领域,例如基于特征点的图像匹配、基于特征点的定位与三维重建。
角点是图像中某些属性较为突出的像素点,
例如像素值最大或者最小的点、线段的顶点、孤立
的边
缘点等.常用的角点有以下几种:
•
灰度梯度值的最大值对应的像素点.
•
两条直线或者曲线的交点.
•
一阶梯度的导数最大值和梯度方向变化率最大的像素点.
•
一阶导数值最大,但是二阶导数值为0
的像素点.
1.绘制关键点
Keypoint类原型:
void visionagin:: Mydrawkeypoint()
{
Mat img = imread("C:\\Users\\86176\\Downloads\\visionimage\\gaoda.jfif");
if (img.empty() == true)
{
cout << "读取失败!" << endl;
}
imshow("原图", img);
//Mat gry;
//cvtColor(img, gry, COLOR_BGR2GRAY);
vector<KeyPoint> key_points;
RNG rng(10086);
//生成100个关键点
for (int i = 0; i < 100; ++i)
{
KeyPoint p;
p.pt.x = rng.uniform(0, img.rows + 1);
p.pt.y = rng.uniform(0, img.cols + 1);
key_points.push_back(p);
}
Mat result;
//绘制
drawKeypoints(img, key_points, result, Scalar(-1), DrawMatchesFlags::DEFAULT);
imshow("result", result);
}
2.Harris角点检测:
void visionagin:: MyHarrisdetect()
{
Mat img = imread("C:\\Users\\86176\\Downloads\\visionimage\\women.jfif");
if (img.empty() == true)
{
cout << "读取失败!" << endl;
}
//resize(img, img, Size(600, 720));
imshow("原图", img);
Mat gry;
cvtColor(img, gry, COLOR_BGR2GRAY);
Mat HarrisMat;
int blocksize = 2;//邻域大小
int sobelsize = 3;//sobel算子size,一般3,5
double k = 0.02;//Harris评价系数R的权重系数,一般为0.04
cornerHarris(gry, HarrisMat, blocksize, sobelsize, k);
//将结果归一化到0-255
Mat Harris_out;
normalize(HarrisMat, Harris_out, 0, 255,NORM_MINMAX);
//将数据转化到CV_8U
convertScaleAbs(Harris_out, Harris_out);
imshow("系数矩阵", Harris_out);
vector<KeyPoint> keypoints;
int num = 0;
for (int i = 0; i < Harris_out.rows; ++i)
{
for (int j = 0; j < Harris_out.cols; ++j)
{
int R = Harris_out.at<uchar>(i, j);//Harris评价系数R
if (R > 125)//大于阈值的系数
{
num++;
KeyPoint p;
p.pt.x = j;
p.pt.y = i;
keypoints.push_back(p);
cout << "(x,y): " << p.pt << endl;
}
}
}
cout << "大于阈值的Harris角点数目是:" << num << endl;
Mat result;
drawKeypoints(gry, keypoints, result);
imshow("result", result);
}
3.Shi-Tomas角点检测
void visionagin:: Myshitomasdetect()
{
Mat img = imread("C:\\Users\\86176\\Downloads\\visionimage\\women.jfif");
if (img.empty() == true)
{
cout << "读取失败!" << endl;
}
//resize(img, img, Size(600, 720));
imshow("原图", img);
Mat gry;
cvtColor(img, gry, COLOR_BGR2GRAY);
vector<Point2f> shitomas;
int maxcorners = 50;
double level = 0.01;
double mindis = 0.04;
goodFeaturesToTrack(gry, shitomas, maxcorners, level, mindis, Mat());
vector<KeyPoint> keypoints;
for (int i = 0; i < shitomas.size(); ++i)
{
KeyPoint p;
p.pt = shitomas[i];
keypoints.push_back(p);
}
Mat result;
drawKeypoints(img, keypoints, result);
imshow("result", result);
}
4.亚像素级别角点检测
无论是
Harris
角点检测还是 Shi-Tomas
角点检测,
Op
e
n
C
V
提供的相关函数都只能得到像素级别的角点,即角点坐标是整数
但是有时在实际的项目或者任务中需要更高精度的亚像素级别的角点坐标.
void visionagin:: Mycornersubpix()
{
Mat img = imread("C:\\Users\\86176\\Downloads\\visionimage\\women.jfif");
if (img.empty() == true)
{
cout << "读取失败!" << endl;
}
imshow("原图", img);
Mat gry;
cvtColor(img, gry, COLOR_BGR2GRAY);
vector<Point2f>shitomaspt;
int maxcorners = 50;
double level = 0.01;
double mindis = 0.04;
goodFeaturesToTrack(gry, shitomas, maxcorners, level, mindis, Mat());
vector<Point2f>shitomassub = shitomaspt;
Size winsize = Size(5, 5);
Size zerosize = Size(-1, -1);
TermCriteria T = TermCriteria(TermCriteria::COUNT + TermCriteria::EPS, 40, 0.01);
cornerSubPix(gry, shitomassub, winsize, zerosize, T);
for (int i = 0; i < shitomassub.size(); ++i)
{
KeyPoint p;
p.pt = shitomassub[i];
cout << "粗坐标: "<<shitomaspt[i]<<"精细后: "<<p.pt << endl;
}
}