opencv---c++实现Moravec算子

#include<opencv2/opencv.hpp>
#include"opencv2/highgui/highgui.hpp"  
#include<iostream>
#include<stdio.h>
#include<math.h>


using namespace std;
using namespace cv;

uchar getpix(Mat& src,int x, int y)
{
	uchar* pt = src.ptr<uchar>(y);
	return pt[x];
}
void setMatpix(Mat& dst, int x, int y, float value)
{
	uchar* pt = dst.ptr<uchar>(y);
	pt[x] = value;
}
/*
src:输入图像
kernel:移动的窗口的大小
threshold:设置的阀值大小
*/
void Moravec(Mat& src, int kernal, float threshold, vector<Point>* corPoint)
{
	int halfKernal = kernal/2;
	//float moveValue[4] = { 0 };
	float minValue;
	Mat dst(src.size(),CV_8UC1,Scalar(0));
	//遍历图像时候,没有对图像的边缘进行处理(边缘是窗口大小一半)
	for (int y = halfKernal; y < src.rows - halfKernal; y++)
	{
		
		for (int x = halfKernal; x < src.cols - halfKernal; x++)
		{
			float moveValue[4] = { 0 };
			//对图像的每一个点在 0°、45°、90°135°的变化量
			for (int win = -halfKernal; win < halfKernal; win++)
			{
				moveValue[0] += pow(getpix(src, x + win, y) - getpix(src, x + win + 1, y), 2);//0°方向变化量
				moveValue[1] += pow(getpix(src, x + win, y + win) - getpix(src, x + win + 1, y + win + 1), 2);//45°方向变化量
				moveValue[2] += pow(getpix(src, x, y + win) - getpix(src, x, y + win + 1), 2);//90°方向变化量
				moveValue[3] += pow(getpix(src, x - win, y + win) - getpix(src, x - win - 1, y + win + 1), 2);//135°方向变化量

			}
			//计算四个方向移动的最小值
			minValue = moveValue[0];
			minValue = minValue > moveValue[1] ? moveValue[1] : minValue;
			minValue = minValue > moveValue[2] ? moveValue[2] : minValue;
			minValue = minValue > moveValue[3] ? moveValue[3] : minValue;

			setMatpix(dst, x, y, minValue);
			
		}
	}
	//获取角点坐标
	float maxValue ;
	int flag;
	Point maxLoc;
	float value;
	
	for (int y = halfKernal; y < src.rows - halfKernal;)
	{
		for (int x = halfKernal; x < src.cols - halfKernal;)
		{
			maxValue = 0;
			value = 0;
			flag = 0;
			maxLoc.x = -1;
			maxLoc.y = -1;
			//计算点(x,y)位中心的kernal的局部最大值。
			for (int winy = -halfKernal; winy <= halfKernal; winy++)
			{
			
				for (int winx = -halfKernal; winx <= halfKernal; winx++)
				{
					value = getpix(dst, x + winx, y + winy);
					if (value > maxValue)
					{

						maxValue = value;
						maxLoc.x = x + winx;
						maxLoc.y = y + winy;
						flag = 1;
					}

				}

			}

			//判断是不是角点
			if (flag == 1 && (maxValue > threshold))
			{
				//cout << maxLoc << endl;
				
				corPoint->push_back(maxLoc);

			}
			x = x + kernal;
		}
		y = y + kernal;
	}
}


int main()
{
	Mat src,src_gray;
	int k = 5;
	float threshold = 200;
	vector<Point>cornerPoint;
	vector<Point>::iterator itr;
	src = imread("d:/picture/5.jpg");
	
	if (src.empty())
	{
		cout << "could not load the image....";
		return -1;
	}
	cvtColor(src, src_gray, COLOR_BGR2GRAY);
	Moravec(src_gray, k, threshold, &cornerPoint);
	for (itr = cornerPoint.begin(); itr <cornerPoint.end(); itr++)
	{
		circle(src, *itr, 5, Scalar(255, 0, 0));
	}
	namedWindow("win");
	imshow("win", src);
	waitKey(0);
	return 0;
}

关于Moravec算子的原理请参考:http://blog.csdn.net/carson2005/article/details/39642923

  • 2
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值