《学习OpenCV》练习8-1(有问题,未解决,求高人指教)

使用两个滑动条与仿射变换函数,可以实现图像的缩放与旋转;使用另外一个滑动条,可以实现图像阈值化阈值的设置,然后根据阈值化后的二值图像画出图像的轮廓;最后想利用cvFindDominantPoints函数实现查找关键点功能,但失败,原因还在查找当中,求高人指教。

#include "cv.h"
#include "highgui.h"
#include "stdio.h"
#include 				//函数cvFindDominantPoints()在此里面

//*****************************************************
//全局变量
//*****************************************************
IplImage* g_img_sorce = NULL;						//源图像
IplImage* g_img_affine = NULL;						//仿射转换的图像
IplImage* g_img_thresh = NULL;						//二值化(阈值化)的图像
IplImage* g_img_contours = NULL;					//轮廓图像
CvMat* g_rot_mat = cvCreateMat( 2, 3, CV_32FC1 );	//旋转映射矩阵
int g_angle = 0;									//图像旋转的角度
int g_scale = 0;									//图像缩放的规模
int g_thresh = 100;									//图像阈值化阈值的大小
int g_max_angle = 360;								//图像旋转最大的角度
int g_max_scale = 50;								//图像缩小的最大倍数,默认为50
int g_max_thresh = 255;								//图像阈值化的最大值,默认为255
CvMemStorage* g_storage = NULL;						//储存轮廓序列的内存
CvMemStorage* g_storage_dp = NULL;					//储存图像关键点的内存


//***********************************************************
//滑动条回调函数:根据滑动条不同位置设置图像顺时针旋转的角度
//***********************************************************
void angle_trackbar(int) 
{
	CvPoint2D32f center = cvPoint2D32f( g_img_sorce->width/2, g_img_sorce->height/2 );	//旋转的中心
	double angle = (double)g_angle;														//旋转的角度,范围为0到360
	double scale = 1-g_scale/(g_max_scale+1.0);											//缩小的尺寸范围为1到(1/51)
	cv2DRotationMatrix( center, angle, scale, g_rot_mat );								//生成映射矩阵
	cvWarpAffine( g_img_sorce, g_img_affine, g_rot_mat );								//仿射变换
	cvShowImage( "affine_transform", g_img_affine );									//显示变换后的图像
}


//***********************************************************
//滑动条回调函数:根据滑动条不同位置设置图像缩小的尺寸
//***********************************************************
void scale_trackbar(int) 
{
	CvPoint2D32f center = cvPoint2D32f( g_img_sorce->width/2, g_img_sorce->height/2 );
	double angle = (double)g_angle;
	double scale = 1-g_scale/(g_max_scale+1.0);
	cv2DRotationMatrix( center, angle, scale, g_rot_mat );
	cvWarpAffine( g_img_sorce, g_img_affine, g_rot_mat );
	cvShowImage( "affine_transform", g_img_affine );
}


//***********************************************************
//滑动条回调函数:根据滑动条不同位置设置图像阈值化阈值的值
//***********************************************************
void thresh_trackbar(int) 
{
	/*如果存储器为空,即程序刚开始执行时,以源图像尺寸创建单通道图像,并创建默认指向64KB的内存存储器指针*/
	if (g_storage==NULL || g_storage_dp==NULL) 
	{
		g_img_thresh = cvCreateImage( cvGetSize(g_img_sorce), IPL_DEPTH_8U, 1 );
		g_img_contours = cvCreateImage( cvGetSize(g_img_sorce), IPL_DEPTH_8U, 1 );
		g_storage = cvCreateMemStorage(0);
		g_storage_dp = cvCreateMemStorage(0);
	} 
	/*如果存储器非空,即已被使用,即程序不是刚开始执行(滑动条的移动会进入此函数),则清空存储器内容*/
	else 
	{
		cvClearMemStorage( g_storage );
		cvClearMemStorage( g_storage_dp );
	}

	/*将图像转换成单通道,并阈值化:若某像素大于g_thresh,则其值为g_max_thresh,否则为0*/
	cvCvtColor( g_img_affine, g_img_thresh, CV_BGR2GRAY );
	cvThreshold( g_img_thresh, g_img_thresh, g_thresh, g_max_thresh, CV_THRESH_BINARY );
	cvShowImage( "thresh_transform", g_img_thresh );									
	
	/*查找g_thresh图像的轮廓,找到的轮廓记录与内存器g_storage,contours指向轮廓树的首地址*/
	CvSeq* contour = 0;
	cvFindContours( g_img_thresh, g_storage, &contour );

	/*处理后将g_threshold,g_contours清零,因为执行cvFindContours()时g_threshold会被直接涂改*/
	cvZero( g_img_thresh );
	cvZero( g_img_contours );

	/*如果轮廓非空,则在g_contours图像上画出该轮廓,轮廓与孔的颜色为白色,最后显示图像*/
	if (contour)
	{
		cvDrawContours( g_img_contours, contour, cvScalarAll(255), cvScalarAll(255), 100 );
	}
	cvShowImage( "contours", g_img_contours );

	///*显示关键点dominant points的数目、坐标*/
	//CvSeq* seq_dps = 0;
	//CvPoint dps;
	//seq_dps = cvFindDominantPoints( contour, g_storage, CV_DOMINANT_IPAN );
	//printf( "find %d dominant points.\n", seq_dps->total );
	//for (int i=0; itotal; i++)
	//{
	//	dps = *(CvPoint*)cvGetSeqElem( seq_dps, i );
	//	printf( "[%d,%d]\n", dps.x, dps.y );
	//}
	//cvWaitKey(0);
}


//*****************************************************
//主函数
//*****************************************************
int main()
{
	/*确保源图像载入*/
	g_img_sorce = cvLoadImage( "E:\\...\\picture_1.jpg", CV_LOAD_IMAGE_COLOR );
	assert( g_img_sorce != NULL );

	/*克隆源图像,并指定原点*/
	g_img_affine = cvCloneImage( g_img_sorce );
	g_img_affine->origin = g_img_sorce->origin;

	/*生成窗口,显示图像*/
	cvNamedWindow( "affine_transform", CV_WINDOW_AUTOSIZE );
	cvNamedWindow( "thresh_transform", CV_WINDOW_AUTOSIZE );
	cvNamedWindow( "contours", CV_WINDOW_AUTOSIZE );
	cvShowImage( "affine_transform", g_img_affine );

	/*在同一幅图像中生成两个滑动条:第一个控制图像顺时针旋转的角度;第二个控制图像缩小的尺寸*/
	cvCreateTrackbar( "angle", "affine_transform", &g_angle, g_max_angle, angle_trackbar );
	cvCreateTrackbar( "scale", "affine_transform", &g_scale, g_max_scale, scale_trackbar );

	/*在img_thresh中生成滑动条,控制阈值的大小*/
	cvCreateTrackbar( "thresh", "thresh_transform", &g_thresh, g_max_thresh, thresh_trackbar );
	thresh_trackbar(0);

	/*释放内存,销毁窗口*/
	cvWaitKey(0);
	cvReleaseImage( &g_img_affine );
	cvReleaseImage( &g_img_thresh );
	cvReleaseMat( &g_rot_mat );
	cvDestroyAllWindows();

	return 0;
}

《学习OpenCV》练习8-1(有问题,未解决,求高人指教)_第1张图片 《学习OpenCV》练习8-1(有问题,未解决,求高人指教)_第2张图片 《学习OpenCV》练习8-1(有问题,未解决,求高人指教)_第3张图片

如果加上查找、显示关键点的一段代码:

///*显示关键点dominant points的数目、坐标*/
	//CvSeq* seq_dps = 0;
	//CvPoint dps;
	//seq_dps = cvFindDominantPoints( contour, g_storage, CV_DOMINANT_IPAN );
	//printf( "find %d dominant points.\n", seq_dps->total );
	//for (int i=0; itotal; i++)
	//{
	//	dps = *(CvPoint*)cvGetSeqElem( seq_dps, i );
	//	printf( "[%d,%d]\n", dps.x, dps.y );
	//}
	//cvWaitKey(0);

则显示以下错误:

《学习OpenCV》练习8-1(有问题,未解决,求高人指教)_第4张图片

你可能感兴趣的:(OpenCV)