//例6-1 使用cvHoughCircles返回在灰度图像中找到的圆序列 //输入:程序名 图像名 //输出:带有圆序列的图像 #include "stdafx.h" #include <cv.h> #include <highgui.h> #include <math.h> int main(int argc, char** argv) { cvNamedWindow("lala",1); IplImage* image=cvLoadImage(argv[1],CV_LOAD_IMAGE_GRAYSCALE);//以灰度格式载入图像 cvShowImage("原图像",image); CvMemStorage* storage=cvCreateMemStorage(0);//bolck_size默认为0 cvSmooth(image,image,CV_GAUSSIAN,5,5);//进行高斯平滑处理,模糊了点 cvShowImage("高斯5,5处理之后",image); CvSeq* result=cvHoughCircles(image,storage,CV_HOUGH_GRADIENT,2,image->width/10); for (int i=0;i<result->total;i++) { float* p=(float*)cvGetSeqElem(result,i); CvPoint pt=cvPoint(cvRound(p[0]),cvRound(p[1])); cvCircle(image,pt,cvRound(p[2]),CV_RGB(0xff,0xff,0xff)); } cvShowImage("霍夫变换处理之后",image); cvWaitKey(0); cvReleaseImage(&image); cvDestroyWindow("lala"); return 0; } //运行结果截图在6-1运行结果.JPG //例 6-2 仿射变换 //输入:程序名 图像 //输出:变换后的图像 #include "stdafx.h" #include <cv.h> #include <highgui.h> int main(int argc, char** argv) { cvNamedWindow("Affine_Transform",1); CvPoint2D32f srcTri[3],dstTri[3]; CvMat* rot_mat=cvCreateMat(2,3,CV_32FC1); CvMat* warp_mat=cvCreateMat(2,3,CV_32FC1); IplImage *src,*dst; if ((argc==2)&&((src=cvLoadImage(argv[1],1))!=0)) { dst=cvCloneImage(src); dst->origin=src->origin; cvZero(dst); //计算warp矩阵 srcTri[0].x=0; srcTri[0].y=0; srcTri[1].x=src->width-1; srcTri[1].y=0; srcTri[2].x=0; srcTri[2].y=src->height-1; dstTri[0].x=src->width*0.0; dstTri[0].y=src->height*0.33; dstTri[1].x=src->width*0.85; dstTri[1].y=src->height*0.25; dstTri[2].x=src->width*0.15; dstTri[2].y=src->height*0.7; cvGetAffineTransform(srcTri,dstTri,warp_mat); cvWarpAffine(src,dst,warp_mat); cvCopy(dst,src); CvPoint2D32f center=cvPoint2D32f(src->width/2,src->height/2); double angle=-50.0; double scale=0.6; cv2DRotationMatrix(center,angle,scale,rot_mat); //转换 cvWarpAffine(src,dst,rot_mat); cvShowImage("Affine_Transform",dst); cvWaitKey(0); } cvReleaseImage(&dst); cvReleaseMat(&rot_mat); cvReleaseMat(&warp_mat); cvDestroyAllWindows(); return 0; } //程序运行截图在:6-2运行结果.JPG //例 6-3 透视变换代码 //输入:程序名 原图像 //输出:变换后的图像 #include "stdafx.h" #include <cv.h> #include <highgui.h> int main(int argc,char** argv) { CvPoint2D32f srcQuad[4],dstQuad[4]; CvMat* warp_matrix=cvCreateMat(3,3,CV_32FC1); IplImage *src,*dst; if ((argc==2)&&((src=cvLoadImage(argv[1]))!=0)) { dst=cvCloneImage(src); dst->origin=src->origin; cvZero(dst); srcQuad[0].x=0; srcQuad[0].y=0; srcQuad[1].x=src->width-1; srcQuad[1].y=0; srcQuad[2].x=0; srcQuad[2].y=src->height-1; srcQuad[3].x=src->width-1; srcQuad[3].y=src->height-1; dstQuad[0].x=src->width*0.05; dstQuad[0].y=src->height*0.33; dstQuad[1].x=src->width*0.9; dstQuad[1].y=src->height*0.25; dstQuad[2].x=src->width*0.2; dstQuad[2].y=src->height*0.7; dstQuad[3].x=src->width*0.8; dstQuad[3].y=src->height*0.9; cvGetPerspectiveTransform(srcQuad,dstQuad,warp_matrix); cvWarpPerspective(src,dst,warp_matrix); cvNamedWindow("Perspective_Warp",1); cvShowImage("Perspective_Warp",dst); cvWaitKey(0); } cvReleaseImage(&dst); cvDestroyAllWindows(); return 0; } //程序运行截图在 6-3运行结果.JPG //例 6-4 对数极变换 //输入:程序名 图像名 一个浮点数,程序默认为40 //输出:变换之后的图像 #include "stdafx.h" #include <cv.h> #include <highgui.h> #include <cxcore.h> int main(int argc, char** argv) { cvNamedWindow("lala",1); IplImage* src1=cvLoadImage(argv[1],1); cvShowImage("原图像src1",src1); //double M=atof(argv[2]);//以浮点形式读取 double M=40; IplImage* dst=cvCreateImage(cvGetSize(src1),8,3);//depth=8,channels=3 IplImage* src2=cvCreateImage(cvGetSize(src1),8,3); //cvShowImage("src2 create 之后",src2);//正确运行,灰的 cvLogPolar(src1,dst,cvPoint2D32f(src1->width/4,src1->height/2),M,CV_INTER_LINEAR+CV_WARP_FILL_OUTLIERS); //输入图像,输出图像,变换的中心,幅度的尺度参数, //(填充输出图像所有像素,如果这些点有和外点对应的,则置零)+ //(表示矩阵由输出图像到输入图像的逆变换,并且因此可以直接用于像素插值。否则,函数从map_matrix中寻找逆变换) cvShowImage("极数变换,原图像,1+8。本图像dst",dst); cvLogPolar(src1,src2,cvPoint2D32f(src1->width/4,src1->height/2),M,CV_INTER_LINEAR|CV_WARP_INVERSE_MAP); cvShowImage("极数变换,原图像,1|16。本图像src2",src2); cvLogPolar(dst,src2,cvPoint2D32f(src1->width/4,src1->height/2),M,CV_INTER_LINEAR|CV_WARP_INVERSE_MAP); cvShowImage("极数变换,dst,1|16。本图像src2",src2); cvWaitKey(0); cvReleaseImage(&src1); cvReleaseImage(&src2); cvReleaseImage(&dst); cvDestroyWindow("lala"); return 0; } //总结: //亏死啦,把输出图像的参数格式弄错了,费了半天劲 /* //以下是参考例题,经运行,正常 #include "stdafx.h" #include <cv.h> #include <highgui.h> #include <cxcore.h> int main(int argc, char** argv) { IplImage* src; if( (argc == 2 )&& ((src=cvLoadImage(argv[1],1)) != 0 )) { cvNamedWindow("原图像",1); cvShowImage("原图像",src); IplImage* dst = cvCreateImage( cvGetSize(src), 8, 3 ); IplImage* src2 = cvCreateImage( cvGetSize(src), 8, 3 ); cvLogPolar( src, dst, cvPoint2D32f(src->width/2,src->height/2), 40, CV_INTER_LINEAR+CV_WARP_FILL_OUTLIERS ); cvLogPolar( dst, src2, cvPoint2D32f(src->width/2,src->height/2), 40, CV_INTER_LINEAR+CV_WARP_FILL_OUTLIERS+CV_WARP_INVERSE_MAP ); cvNamedWindow( "log-polar(极数变换)", 1 ); cvShowImage( "log-polar(极数变换)", dst ); cvNamedWindow( "inverse log-polar(反逆极数变换)", 1 ); cvShowImage( "inverse log-polar(反逆极数变换)", src2 ); cvWaitKey(); } return 0; } */ //例6-5 用cvDFT()加快卷积计算(离散傅立叶变换) //本例用于熟悉流程,没有输入,固定矩阵,逐步查看结果 #include "stdafx.h" #include <cv.h> #include <highgui.h> void printMat( CvMat* M) { printf("/n/n%d*%d:",M->rows,M->cols); for (int i=0;i<M->rows;i++) { printf("/n第%d行:/n",i); for (int j=0;j<M->cols;j++) { float temp=0; temp=CV_MAT_ELEM(*M,float,i,j); printf(" %f",temp); } } } int main(int argc, char** argv) { CvMat* A=cvCreateMat(2,3,CV_32FC1);//size:M1*N1,这里2*3 float vals1[]={1,2,3,4,5,6}; cvInitMatHeader(A,2,3,CV_32FC1,vals1); //printMat(A);//成功 /* 2*3: 第0行: 1.000000 2.000000 3.000000 第1行: 4.000000 5.000000 6.000000 */ CvMat* B=cvCreateMat(3,4,CV_32FC1);//size:M2*N2,这里3*4 float vals2[]={7,8,9,10,11,12,13,14,15,16,17,18}; cvInitMatHeader(B,3,4,CV_32FC1,vals2); //printMat(B);//成功 /* 3*4: 第0行: 7.000000 8.000000 9.000000 10.000000 第1行: 11.000000 12.000000 13.000000 14.000000 第2行: 15.000000 16.000000 17.000000 18.000000 */ CvMat* C=cvCreateMat(4,6,CV_32FC1);//size:(A->rows+B->rows-1)*(A->cols+B->cols-1),这里4*6 float vals3[]={19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42}; cvInitMatHeader(C,4,6,CV_32FC1,vals3); //printMat(C);//成功 /* 4*6: 第0行: 19.000000 20.000000 21.000000 22.000000 23.000000 24.000000 第1行: 25.000000 26.000000 27.000000 28.000000 29.000000 30.000000 第2行: 31.000000 32.000000 33.000000 34.000000 35.000000 36.000000 第3行: 37.000000 38.000000 39.000000 40.000000 41.000000 42.000000 */ int dft_M=cvGetOptimalDFTSize(A->rows+B->rows-1);//获取向量的长度,返回一个相等或者较大的合适尺寸值 //printf("/ndft_M=%d",dft_M);//结果为4 int dft_N=cvGetOptimalDFTSize(A->cols+B->cols-1); //printf("/ndft_N=%d",dft_N);//结果为6 CvMat* dft_A=cvCreateMat(dft_M,dft_N,A->type);//4*6,浮点型,-431602080.000000 CvMat* dft_B=cvCreateMat(dft_M,dft_N,B->type);//4*6,浮点型,-431602080.000000 CvMat tmp; //printf("here");//声明成功 cvGetSubRect(dft_A,&tmp,cvRect(0,0,A->cols,A->rows));//返回输入的图像或矩阵的矩形数组子集的矩阵头 //arr:输入数组。submat:指向矩形数组子集矩阵头的指针。rect:以0坐标为基准的ROI。 cvCopy(A,&tmp); //printMat(A);//还是以前的 cvGetSubRect(dft_A,&tmp,cvRect(A->cols,0,dft_A->cols-A->cols,A->rows)); //printMat(&tmp);//2*3的-431602080.000000 cvZero(&tmp); //printMat(&tmp);//全成了0 cvDFT(dft_A,dft_A,CV_DXT_FORWARD,A->rows);//CV_DXT_FORWARD:0 //printMat(dft_A);//做了傅立叶变换,我不认识了...... /* 4*6: 第0行: 21.000000 4.000000 -13.856405 -3.000000 1.732050 7.000000 第1行: 6.000000 -9.026278 -7.830127 -0.633975 2.366025 2.000000 第2行: -15.000000 -3.000000 5.196152 0.000000 0.000000 -5.000000 第3行: -9.000000 10.026278 -0.830127 -2.366025 -0.633975 -3.000000 */ cvGetSubRect(dft_B,&tmp,cvRect(0,0,B->cols,B->rows)); cvCopy(B,&tmp); cvGetSubRect(dft_B,&tmp,cvRect(B->cols,0,dft_B->cols-B->cols,B->rows)); cvZero(&tmp); cvDFT(dft_B,dft_B,CV_DXT_FORWARD,B->rows); //printMat(dft_B);//做了傅立叶变换,我不认识了...... /* 4*6: 第0行: 150.000000 -10.499998 -64.951904 37.500000 2.598076 -6.000000 第1行: -32.000000 -21.650637 17.356407 -7.133974 -12.499998 0.000000 第2行: -50.000000 -3.500000 -21.650633 12.500001 0.866024 2.000000 第3行: 50.000000 21.650637 10.356408 -8.866026 12.500000 -2.000000 */ cvMulSpectrums(dft_A,dft_B,dft_A,0);//频谱乘法,A=A*B //printMat(dft_A);//更不认识了 /* 4*6: 第0行: 3150.000000 -941.999878 -114.315392 -117.000000 57.157654 -42.000000 第1行: -942.000000 331.327545 12.863465 34.098072 -8.954475 10.000000 第2行: 180.000000 122.999977 46.765366 -0.000000 0.000003 4.000000 第3行: -450.000000 225.672440 85.863457 28.901924 -23.954475 6.000000 */ cvDFT(dft_A,dft_A,CV_DXT_INV_SCALE,C->rows);//CV_DXT_INV_SCALE:3,C->rows:4 //printMat(dft_A);//不认识 /* 4*6: 第0行: 7.000010 22.000006 45.999996 51.999992 46.999996 30.000006 第1行: 39.000011 101.000015 188.000000 209.000000 171.000000 102.000015 第2行: 59.000011 149.000015 272.000000 293.000000 235.000000 138.000000 第3行: 60.000000 139.000000 238.000000 253.000000 192.000000 108.000000 */ cvGetSubRect(dft_A,&tmp,cvRect(0,0,C->cols,C->rows));//相当于复制 //printMat(dft_A); cvCopy(&tmp,C); //printMat(&tmp);//和现在的dft_A是一样的 //printMat(C);//和现在的dft_A是一样的 cvReleaseMat(&dft_A); cvReleaseMat(&dft_B); cvWaitKey(0); return 0; } 使用图像进行傅立叶变换还没有实现