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

来源:互联网 发布:抗干扰强的单片机 编辑:程序博客网 时间:2024/05/17 03:19
#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