#include <stdio.h>//***********************************解决opencv问题的万能头文件//
#include <tchar.h>
#include<opencv2/legacy/legacy.hpp>
#include<iomanip>
#include <fstream>
#include<opencv.hpp>
#include<highgui.h>
#include<opencv2\features2d\features2d.hpp>
#include<nonfree\nonfree.hpp>
#include<windows.h>
#include<opencv2/opencv.hpp>
#include"opencv2/highgui/highgui.hpp"
using namespace cv;
using namespace std;
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 = 220;
vector<Point>cornerPoint;
vector<Point>::iterator itr;
src = imread("F:\\jiance.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);
system("pause");
return 0;
}