⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 12-1.cpp

📁 基于OpenCV的计算机视觉技术实现.rar
💻 CPP
字号:



#pragma comment (lib,"highgui.lib")
#pragma comment (lib,"cxcore.lib")
#pragma comment (lib,"cv.lib")



#include <cv.h>
#include <highgui.h>
#include <stdio.h>
#include <iostream.h>

//指定矩形区域内角点阵列的行数目(满足该条件才保存检测出角点的坐标到文件)
#define rank_num   6	
//指定矩形区域内角点阵列的列数目(满足该条件才保存检测出角点的坐标到文件)
#define col_num    6	


IplImage *srcImage = 0;					//存储读入的图像
IplImage *ImageShow = 0;				//存储显示带角点的图像
IplImage *grayImage= 0;				//原始图像转变的灰度图像
IplImage *corners1 = 0;					//临时图像
IplImage *corners2 = 0; 				//临时图像

#define max_corners 200				//限定最大能找到的角点数

int cornerCount=max_corners;			//实际检测的角点数目

int qualityLevel=0;						//最小质量因子  
int minDistance=40;					//角点的最小距离。这里使用 Euclidean 距离 

CvScalar color = CV_RGB(255,0,0);		//所绘制角点的颜色(红色

CvPoint2D32f corners[max_corners];		//检测存储角点的点数组

CvRect ROI_rect;						//指定检测角点的矩形区域的范围

char chek_area_state=0;			//指定角点检测范围的时候用的 (画拖动时的矩形框的)



//---------------------本程序用到的函数---------------------------------------------


//-----滑动条响应函数(检测角点就在该函数里实现)---
void re_find_corners(int ) ;

//----鼠标响应函数(主要用于确定寻找角点的矩形区域范围)----
void on_mouse( int event, int x, int y, int flags, void* param ) ;

//----角点排序函数(对寻找到的角点进行重新排序 )----------

void corners_sort() ;			



//----------以下为main主函数-----------------

void  main( )
{
  
    //载入原始图像
    //srcImage = cvLoadImage("黑白格.jpg",-1);

	srcImage = cvLoadImage("Image044_00.jpg",-1);	
    
    grayImage = cvCreateImage(cvGetSize(srcImage), IPL_DEPTH_8U, 1);

	cout<<"srcImage的信道数目:"<<srcImage->nChannels<<endl;
    
    //当原始图像是RGB彩色图时转为为灰度图 不然直接拷贝.
	if ( srcImage->nChannels  > 1)
	{
		cvCvtColor(srcImage, grayImage, CV_BGR2GRAY);
	}

	else
	{
		grayImage=cvCloneImage(srcImage);				
	}

	//---------设置角点检测的矩形区域范围----------------------------
	ROI_rect.x=0;
	ROI_rect.y=0;
	ROI_rect.width = grayImage->width;
	ROI_rect.height = grayImage->height;

	//----一开始默认是整幅图像--------
	cvSetImageROI(grayImage, ROI_rect);	

	//----临时图像创建角点检测函数cvGoodFeaturesToTrack中需要----
	corners1= cvCreateImage(cvGetSize(grayImage), IPL_DEPTH_32F, 1);
    corners2= cvCreateImage(cvGetSize(grayImage),IPL_DEPTH_32F, 1);

	//---------显示图像窗口"image"------------
	       
    cvNamedWindow( "image", 0 );		//改成1的话 下面那句resize就没用啦

    cvResizeWindow("image",950,768);

	//-----滑动条qualityLevel和minDistance改变角点检测的最小质量因子和最小距离-----

	cvCreateTrackbar("qualityLevel", "image", &qualityLevel, 100, re_find_corners);
    cvCreateTrackbar("minDistance",  "image", &minDistance,	 200, re_find_corners);
   	
	//------调用以显示检测出的角点---------
    re_find_corners(0);

	//----------鼠标效应函数cvSetMouseCallback------------------

	cvSetMouseCallback(	"image", on_mouse, 0 );

	//-------------确定角点检测范围的提示----------------------

	cout<<endl<<endl
		<<"提示:按下shift建的同时单击鼠标确定角点检测范围的左上角,"<<endl
		<<"      最后鼠标右键确定角点检测范围的右下角"
		<<endl<<endl;
			    
    cvWaitKey(0); // wait for key. The function has

    //------------释放图像------------------
    cvReleaseImage(&srcImage);
    cvReleaseImage(&ImageShow);
    cvReleaseImage(&grayImage);
    cvReleaseImage(&corners1);
    cvReleaseImage(&corners2);

}


//----------------滑动条改变时的响应函数(目的是为了找对应的角点)--------------------

void re_find_corners(int )
{	
	int i=0;
	int radius=2;
	int thickness=2;

	//根据滑动条的改变更新quality_level
	double quality_level=(double)qualityLevel /100 + 0.02;

//根据滑动条的改变更新min_distance
	double min_distance=(double)minDistance;					
		
	//-------- cvGoodFeaturesToTrack检测角点函数----------------
	
	cvGoodFeaturesToTrack(	grayImage, 
							corners1, 
							corners2, 
							corners,
							&cornerCount, 
							quality_level, 
							min_distance, 
							NULL
						);	
	
//-------------重新设置角点的位置(因为在这之前的角点位置是原图像的在ROI区域的)并
//-------------输出角点在图像中的坐标--------------------
			
	if(cornerCount>0) 
	{	
						
		for (i=0; i<cornerCount; i++)
		{			
			corners[i].x=corners[i].x + ROI_rect.x;
			corners[i].y=corners[i].y + ROI_rect.y;	
		}

	}

//只有当rank_num*col_num等于找到的角点数(即满足宏定义条件)时才对它进行排序

	if( (rank_num*col_num)== cornerCount )
	{
		corners_sort();			//对角点进行排序

		cout<<endl<<endl
			<<"找到的角点数等于rank_num*col_num"
			<<endl<<endl;

		//-------------输出排序后角点在图像中的坐标--------------------
		cout<<endl<<endl
			<<"输出排序后角点在图像中的坐标"
			<<endl<<endl;

		for (i=0; i<cornerCount; i++)
		{								
			cout<<corners[i].x<<"  "<<corners[i].y<<endl;					
		}

		//------------存储检测出的角点坐标到文件器----------------------------
		CvFileStorage* fs = cvOpenFileStorage( "points_coordinates.xml", 0, CV_STORAGE_WRITE );

		cvWriteComment(fs, "存储角点的坐标", 0);
		cvWriteRawData( fs, corners, rank_num*col_num*2, "f" );
		cout<<endl<<endl<<"已经存储角点坐标到文件points_coordinates.xml"<<endl<<endl;	
		cvReleaseFileStorage (&fs);	
	}

	
	//-------在原图上绘出角点---------
	
	ImageShow=cvCloneImage(srcImage);	
	
	if(cornerCount>0) 
	{			
		//-------------输出角点在图像中的坐标--------------------
		
		for (i=0; i<cornerCount; i++)
		{			
			//cout<<corners[i].x<<"  "<<corners[i].y<<endl;					
		}

		for (i=0; i<cornerCount; i++)
		{
			cvCircle(ImageShow, 
				cvPoint((int)(corners[i].x), (int)(corners[i].y)),		//圆心坐标
				radius,										//半径
				color, 										//颜色
				thickness,										//线条粗细
				CV_AA, 
				0);
			 
		}
				
	}
	
	printf("num corners found: %d\n", cornerCount);
	
	cornerCount=max_corners;		
	
	//------显示检出角点的图像-----
	cvShowImage( "image", ImageShow ); 		
	
	cvReleaseImage(&ImageShow);	
	
}

//----------------------鼠标效应函数用于设定角点检测的范围-----------------

void on_mouse( int event, int x, int y, int flags, void* param )

{	
	int thickness=1;				//画检测边缘的线条粗细

	CvPoint point1;
	CvPoint point2;
		
	//--------shift和左键按下时确定角点检测范围的左上角--------
	if( (event==CV_EVENT_LBUTTONUP) &&  (flags==CV_EVENT_FLAG_SHIFTKEY) )
	{
		ROI_rect.x=x;					//设置ROI区域的位置点
		ROI_rect.y=y;

		chek_area_state=1;				//表征此时鼠标点击的点作为矩形框的左上角
		
	}

	//--------------动态的画出角点检测范围-------------------

	if( chek_area_state && event==CV_EVENT_MOUSEMOVE)
	{ 

		ImageShow=cvCloneImage(srcImage);				 
		
		point1=cvPoint(ROI_rect.x, ROI_rect.y);
		point2=cvPoint(x,y);

		cvRectangle( ImageShow, 
					point1, 
					point2, 
					color,
					thickness, 
					CV_AA, 
						0
);

		cvShowImage( "image", ImageShow ); 

		cvReleaseImage(&ImageShow);		
	}

	//--------直接右键按下时确定角点检测范围的右下角

	if(  chek_area_state && event==CV_EVENT_RBUTTONUP )		//直接写flags=17也可
	{
		ROI_rect.width  = abs(x - ROI_rect.x);			//设置ROI区域的大小
		ROI_rect.height = abs(y - ROI_rect.y);
				
		cvSetImageROI(grayImage, ROI_rect);				//设置角点检测的ROI区域
		
		corners1= cvCreateImage(cvGetSize(grayImage), IPL_DEPTH_32F, 1);
		corners2= cvCreateImage(cvGetSize(grayImage),IPL_DEPTH_32F, 1);

		cvWaitKey(10);

		//在新设置的范围内重新找角点
		re_find_corners(0);			

		//表征此时鼠标点击的点作为矩形框的右下角,且矩形框已画完了
		chek_area_state=0;	
				
		//-------------确定角点检测范围的提示----------------------
		
		cout<<endl<<endl
			<<"提示:按下shift建的同时单击鼠标确定角点检测范围的左上角,"<<endl
			<<"      最后鼠标右键确定角点检测范围的右下角"
			<<endl<<endl;
		
	}
		
}

void corners_sort()
{	
	CvPoint2D32f temp_point=cvPoint2D32f(0.0,0.0);	//排序时用于交换的临时point
	
	int i=0;
	int j=0;
	int k=0;
	
	
	//-------------先根据point的x值排序---------------
	
	
	for( i=1; i<cornerCount-1; i++ )			//i<cornerCount-1 因为 后面j=i 再j+1了
	{
		for( j=i; j>=0; j-- )
		{
			if( (corners[j].x) > (corners[j+1].x) )
			{
				//-----交换CvPoint--------
				
				temp_point=corners[j];
				corners[j]=corners[j+1];
				corners[j+1]=temp_point;				
				
			}
			
			else;				
			
		}
				
	}
		
	//-------------(rank*colom的点阵)再根据point的y值排序---------------
		
	for( i=0; i<col_num; i++ )					// i代表第几列,
	{
		for( j=0; j<rank_num-1; j++ )				//j代表行数 rank_num-1 因为下面加1啦
		{
			for( k=j; k>=0; k-- )
			{				
				
			
				if( (corners[i*rank_num+k].y) > (corners[i*rank_num+k+1].y) )	 
				{					
					//-----交换点之间的坐标以排序-------
					
					temp_point=corners[i*rank_num+k];
					corners[i*rank_num+k]=corners[i*rank_num+k+1];
					corners[i*rank_num+k+1]=temp_point;					
					
					
				}
				
				else;	
			}
			
		}	
		
	}	
}


//*/

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -