图像处理1---Moravec算子

# include//在新版本的opencv中,所有的头文件都已经涵盖在本行头文件中了
# include 
# include 
# include 
using namespace std;
using namespace cv;

uchar get_pix(Mat *src, int x, int y)
{
	uchar *pt = src->ptr(y);
	return pt[x];
}

void set_mat_pix(Mat *src, int x, int y, float value)
{
	uchar * pt = src->ptr(y);
	pt[x] = value;
}

//Moravec算子
void Moravec(Mat * src, int kenal, float threshold, vector*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;
	vectorcorner_point;
	vector::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 corner_point;定义一个Point类型的容器(动态数组),
	使用corner_point.push_back(变量名)将数值压入数组;
	vector迭代器的生成及使用:vector::iterator itr;定义迭代器名称
							for(itr = itr.begin(); itr

 

你可能感兴趣的:(图像处理)