# include<opencv2/opencv.hpp>//在新版本的opencv中,所有的头文件都已经涵盖在本行头文件中了
# include <iostream>
# include <stdio.h>
# include <math.h>
using namespace std;
using namespace cv;
uchar get_pix(Mat *src, int x, int y)
{
uchar *pt = src->ptr<uchar>(y);
return pt[x];
}
void set_mat_pix(Mat *src, int x, int y, float value)
{
uchar * pt = src->ptr<uchar>(y);
pt[x] = value;
}
//Moravec算子
void Moravec(Mat * src, int kenal, float threshold, vector<Point>*cor_point)
{
int half_kenal = kenal / 2;
float min_value;
Mat dst(src->size(), CV_8UC1, Scalar(0));
//定义Mat的格式方法:Mat a(行,列,类型,值);
// Mat a.creat(行,列,类型);
for (int y = half_kenal; y < src->rows - half_kenal; y++)
{
for (int x = half_kenal; x < src->cols - half_kenal; x++)
{
float move_value[4] = { {0} };
for (int win = -half_kenal; win < half_kenal; win++)
{
//0°方向方差
move_value[0] += powf(get_pix(src, x + win, y) - get_pix(src, x + win + 1, y), 2);
//45°方向方差
move_value[1] += powf(get_pix(src, x + win, y + win) - get_pix(src, x + win + 1, y + win + 1), 2);
move_value[2] += pow(get_pix(src, x, y + win) - get_pix(src, x, y + win + 1), 2);//90°方向变化量
move_value[3] += pow(get_pix(src, x - win, y + win) - get_pix(src, x - win - 1, y + win + 1), 2);
}
min_value = move_value[0];
for (int i = 0; i < 4; i++)
{
if (min_value > move_value[i])
min_value = move_value[i];
else
continue;
}
set_mat_pix(&dst, x, y, min_value);
}
}
//获取角点坐标
float max_value; int flag; Point max_loc; float value;
for (int y = half_kenal; y < src->rows - half_kenal; )
{
for (int x = half_kenal; x < src->cols - half_kenal; )
{
max_value = 0;
value = 0;
flag = 0;
max_loc.x = -1;
max_loc.y = -1;
//计算点(x,y)位中心的kenal的局部最大值
for (int winy = -half_kenal; winy <= half_kenal; winy++)
{
for (int winx = -half_kenal; winx <= half_kenal; winx++)
{
value = get_pix(&dst, x + winx, y + winy);
if (value > max_value)
{
max_value = value;
max_loc.x = x + winx;
max_loc.y = y + winy;
flag = 1;
}
}
}
//判断是否是角点
if (flag == 1 && (max_value > threshold))
{
cor_point->push_back(max_loc);
}
x += kenal;
}
y += kenal;
}
}
int main()
{
Mat src, src_gray;
int k = 5;
float threshold = 254;
vector<Point>corner_point;
vector<Point>::iterator itr;
src = imread("1.png");
if (src.empty())
{
cout << "加载图像失败!!!" << endl;
return -1;
}
cvtColor(src, src_gray, COLOR_RGB2GRAY);//将图像转换为灰度图像
Moravec(&src_gray, k, threshold, &corner_point);
for (itr = corner_point.begin(); itr < corner_point.end(); itr++)
circle(src, *itr, 5, Scalar(255, 0, 0));
namedWindow("win");
imshow("win", src);
waitKey(0);
return 0;
}
/***************************************总结*************************************************************
Point local==>local.x,local.y:可以记录点的坐标;
vector<Point> corner_point;定义一个Point类型的容器(动态数组),
使用corner_point.push_back(变量名)将数值压入数组;
vector迭代器的生成及使用:vector<Point>::iterator itr;定义迭代器名称
for(itr = itr.begin(); itr<itr.end(); itr++)
********************************************************************************************************/
图像处理1---Moravec算子
猜你喜欢
转载自blog.csdn.net/qq_33661910/article/details/81381009
今日推荐
周排行