使用两个滑动条与仿射变换函数,可以实现图像的缩放与旋转;使用另外一个滑动条,可以实现图像阈值化阈值的设置,然后根据阈值化后的二值图像画出图像的轮廓;最后想利用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;
}
如果加上查找、显示关键点的一段代码:
///*显示关键点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);