第22集 Moravec角点检测

步骤1:算出0,45,90,135四个方向上变化的最小值的平方,并且记录在结果图像中

步骤2:求结果图像的局部最大值,并且和阀值对比,大于阀值的保存该点的坐标位置:cvCreateMemStorage ,cvCreateSeq ,cvSeqPush

步骤3:读取角点的坐标,并且在图像上画出:cvGetSeqElem,cvCircle

wKioL1PsdymAV09aAAJvA8JjLPs945.jpg

程序:

#include "cv.h"
#include "cxcore.h"
#include "highgui.h"
#include <iostream>
int CornerDetect(IplImage *src,CvSeq *Corner,int TestWidth,int TestHeight,int Threshold)
{
int CornerNum=0;
int HalfTestHeight=TestHeight/2;
int HalfTestWidth=TestWidth/2;
int ResultWidth=src->width;
int ResultHeight=src->height;
IplImage* ResultImage=cvCreateImage(cvSize(ResultWidth,ResultHeight),32,1);
cvZero(ResultImage);
//计算结果保存在ResultImage中
int i=0;
for(int y=HalfTestHeight;y<src->height-2*HalfTestHeight;y++)
{
for(int x=HalfTestWidth;x<src->width-2*HalfTestWidth;x++)
{
float Result[4]={0};
//0度结果
for(int winx=-HalfTestWidth;winx<HalfTestWidth;winx++)
{
Result[0]=Result[0]+pow(cvGetReal2D(src,y,x+winx)-cvGetReal2D(src,y,x+winx+1),2);
}
//45度结果
for(int winx=-HalfTestWidth;winx<HalfTestWidth;winx++)
{
Result[1]=Result[1]+pow(cvGetReal2D(src,y+winx,x+winx)-cvGetReal2D(src,y+winx+1,x+winx+1),2);
}
//90度结果
for(int winx=-HalfTestWidth;winx<HalfTestWidth;winx++)
{
Result[2]=Result[2]+pow(cvGetReal2D(src,y+winx,x)-cvGetReal2D(src,y+winx+1,x),2);
}
//135度结果
for(int winx=-HalfTestWidth;winx<HalfTestWidth;winx++)
{
Result[3]=Result[3]+pow(cvGetReal2D(src,y+winx,x-winx)-cvGetReal2D(src,y+winx+1,x-winx-1),2);
}
float min=Result[0]<Result[1]?Result[0]:Result[1];
min=Result[2]<min?Result[2]:min;
min=Result[3]<min?Result[3]:min;
cvSetReal2D(ResultImage,y,x,min);
}
}
std::cout<<"dfsaf"<<std::endl;
//计算交点坐标
double max=0;
CvPoint MaxPoint;
for(int y=HalfTestHeight;y<ResultImage->height-HalfTestHeight;y+=HalfTestHeight)
{
for(int x=HalfTestWidth;x<ResultImage->width-HalfTestWidth;x+=HalfTestWidth)
{
for(int winx=-HalfTestWidth;winx<=HalfTestWidth;winx++)
{
for(int winy=-HalfTestHeight;winy<=HalfTestHeight;winy++)
{
double current=cvGetReal2D(ResultImage,y+winy,x+winx);
if(max<current)
{
max=current;
MaxPoint.x=x;
MaxPoint.y=y;
}
}
}
if(max>Threshold)
{
cvSeqPush(Corner,&MaxPoint);
CornerNum++;
std::cout<<"max"<<max<<std::endl;
}
MaxPoint.x=0;
MaxPoint.y=0;
max=0;
}
}
std::cout<<"CornerNum"<<CornerNum<<std::endl;
return CornerNum;
}
int CornerDetection(int argc,char** argv)
{
IplImage* src=cvLoadImage("e:\\picture\\FivePointStar.jpg",0);
cvNamedWindow("FivePointStar");
cvShowImage("FivePointStar",src);
int TestWidth=5;
int TestHeight=5;
CvMemStorage* storage=cvCreateMemStorage(0);
CvSeq* CornerSeq=cvCreateSeq(0,sizeof(CvSeq),sizeof(CvPoint),storage);
int CornerNum=CornerDetect(src,CornerSeq,TestWidth,TestHeight,65020);
IplImage* ResultImage=cvCreateImage(cvGetSize(src),8,3);
cvZero(ResultImage);
cvCvtColor(src,ResultImage,CV_GRAY2BGR);
for(int i=0;i<CornerNum;i++)
{
CvPoint* CornerPoint=(CvPoint*)cvGetSeqElem(CornerSeq,i);
cvCircle(ResultImage,*CornerPoint,5,cvScalar(0,0,255,NULL));
}
cvNamedWindow("ResultImage");
cvShowImage("ResultImage",ResultImage);
cvWaitKey(0);
cvDestroyWindow("FivePointStar");
cvDestroyWindow("ResultImage");
cvReleaseImage(&src);
cvReleaseImage(&ResultImage);
return 0;
}


你可能感兴趣的:(opencv,Moravec,角点检测)