步骤1:算出0,45,90,135四个方向上变化的最小值的平方,并且记录在结果图像中
步骤2:求结果图像的局部最大值,并且和阀值对比,大于阀值的保存该点的坐标位置:cvCreateMemStorage ,cvCreateSeq ,cvSeqPush
步骤3:读取角点的坐标,并且在图像上画出:cvGetSeqElem,cvCircle
程序:
#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; }
第22集 Moravec角点检测
时间: 2024-10-28 21:35:07