opencv仿射变换与透视变换

基本上就是learning opencv一书第4章,练习7的答案了。

先来个自己写的透视变换代码:

[cpp]  view plain copy
  1. //透视变换  
  2. #include <cv.h>  
  3. #include  <highgui.h>  
  4. #include <math.h>  
  5.   
  6. int main(int argc,char** argv)  
  7. {  
  8.     CvPoint2D32f srcQuad[4],dstQuad[4];  
  9.     CvMat* warp_matrix = cvCreateMat(3,3,CV_32FC1);  
  10.     IplImage *src,*dst;  
  11.     src=cvLoadImage("../lena.jpg",1);  
  12.     if(!src)  
  13.         return -1;  
  14.     cvNamedWindow("Perspective_warp",1);  
  15.     int pressKey;  
  16.     int df1(1),df2(1),df3(1),df4(1),df5(1),df6(1),df7(1),df8(1);  
  17.     df1 = 5;df2 = 33;df3 = 90;df4 = 25;df5 = 20;df6 = 70;df7 = 80;df8 = 90;  
  18.     //df1 = df2 = df3 = df4 = df5 = df6 = df7 = df8 = 0;  
  19.     dst = cvCloneImage(src);  
  20.     dst->origin = src->origin;  
  21.     cvZero(dst);  
  22.   
  23.     srcQuad[0].x = 0;  
  24.     srcQuad[0].y = 0;  
  25.     srcQuad[1].x = src->width - 1;  
  26.     srcQuad[1].y = 0;  
  27.     srcQuad[2].x = 0;  
  28.     srcQuad[2].y = src->height - 1;  
  29.     srcQuad[3].x = src->width - 1;  
  30.     srcQuad[3].y = src->height - 1;  
  31.     float delta=0.01;  
  32.     while(1)  
  33.     {  
  34.         //dstQuad[0].x = src->width*delta*(df1%101);  
  35.         //dstQuad[0].y = src->height*delta*(df2%101);  
  36.         //dstQuad[1].x = src->width - 1+src->width*delta*(df3%101);  
  37.         //dstQuad[1].y = src->height*delta*(df4%101);  
  38.         //dstQuad[2].x = src->width*delta*(df5%101);  
  39.         //dstQuad[2].y = src->height - 1+src->height*delta*(df6%101);  
  40.         //dstQuad[3].x = src->width - 1+src->width*delta*(df7%101);  
  41.         //dstQuad[3].y = src->height - 1+src->height*delta*(df8%101);  
  42.   
  43.         dstQuad[0].x = src->width*delta*abs(df1%101);  
  44.         dstQuad[0].y = src->height*delta*abs(df2%101);  
  45.         dstQuad[1].x = src->width*delta*abs(df3%101);  
  46.         dstQuad[1].y = src->height*delta*abs(df4%101);  
  47.         dstQuad[2].x = src->width*delta*abs(df5%101);  
  48.         dstQuad[2].y = src->height*delta*abs(df6%101);  
  49.         dstQuad[3].x = src->width*delta*abs(df7%101);  
  50.         dstQuad[3].y = src->height*delta*abs(df8%101);  
  51.   
  52.         cvGetPerspectiveTransform(srcQuad,dstQuad,warp_matrix);  
  53.         cvWarpPerspective(src,dst,warp_matrix);  
  54. //--------------------------字符显示-----------------------------------------  
  55.         CvFont font = cvFont(1,1);  
  56.         char buf[8];  
  57.         char dspStr1[32] = {'/0'};  //  
  58.         char dspStr2[32] = {'/0'};  //  
  59.         char dspStr3[32] = {'/0'};  //  
  60.   
  61.         memset(buf,'/0',sizeof(buf));  
  62.         strcat(dspStr1,"|");  
  63.         strcat(dspStr1,itoa(abs(df6%101),buf,10));  
  64.         strcat(dspStr1,",");  
  65.         strcat(dspStr1,itoa(abs(df7%101),buf,10));  
  66.         strcat(dspStr1,",");  
  67.         strcat(dspStr1,itoa(abs(df8%101),buf,10));  
  68.         strcat(dspStr1,"|");  
  69.   
  70.         strcat(dspStr2,"|");  
  71.         strcat(dspStr2,itoa(abs(df4%101),buf,10));  
  72.         strcat(dspStr2,",00,");  
  73.         strcat(dspStr2,itoa(abs(df5%101),buf,10));  
  74.         strcat(dspStr2,"|");  
  75. //「」┌└┘┐|  
  76.         strcat(dspStr3,"|");  
  77.         strcat(dspStr3,itoa(abs(df1%101),buf,10));  
  78.         strcat(dspStr3,",");  
  79.         strcat(dspStr3,itoa(abs(df2%101),buf,10));  
  80.         strcat(dspStr3,",");  
  81.         strcat(dspStr3,itoa(abs(df3%101),buf,10));  
  82.         strcat(dspStr3,"|");  
  83.   
  84.         cvPutText(dst,dspStr1,cvPoint(dst->width-120,20),&font,cvScalar(0,0xff));  
  85.         cvPutText(dst,dspStr2,cvPoint(dst->width-120,40),&font,cvScalar(0,0xff));  
  86.         cvPutText(dst,dspStr3,cvPoint(dst->width-120,60),&font,cvScalar(0,0xff));  
  87. //-------------------------------------------------------------------  
  88.         cvShowImage("Perspective_warp",dst);  
  89.         pressKey = cvWaitKey();  
  90.         printf("%x pressed/n",pressKey);  
  91.         switch(pressKey)  
  92.         {  
  93.         case '1':  
  94.             df1++;  
  95.             break;  
  96.         case 0x230000:  
  97.             df1--;  
  98.             break;  
  99.         case '2':  
  100.             df2++;  
  101.             break;  
  102.         case 0x280000:  
  103.             df2--;  
  104.             break;  
  105.         case '3':  
  106.             df3++;  
  107.             break;  
  108.         case 0x220000:  
  109.             df3--;  
  110.             break;  
  111.         case '4':  
  112.             df4++;  
  113.             break;  
  114.         case 0x250000:  
  115.             df4--;  
  116.             break;  
  117.         case '6':  
  118.             df5++;  
  119.             break;  
  120.         case 0x270000:  
  121.             df5--;  
  122.             break;  
  123.         case '7':  
  124.             df6++;  
  125.             break;  
  126.         case 0x240000:  
  127.             df6--;  
  128.             break;  
  129.         case '8':  
  130.             df7++;  
  131.             break;  
  132.         case 0x260000:  
  133.             df7--;  
  134.             break;  
  135.         case '9':  
  136.             df8++;  
  137.             break;  
  138.         case 0x210000:  
  139.             df8--;  
  140.             break;  
  141.         case 27:  
  142.             cvReleaseImage(&dst);  
  143.             cvDestroyWindow("Perspective_warp");  
  144.             cvReleaseMat(&warp_matrix);  
  145.             return 0;  
  146.         default:break;  
  147.         }  
  148.     }  
  149.     return 0;  
  150. }  

这个程序的运行效果,是比较容易分析的,就是变换一张图片的四个角的位置后,引起图像的相应变化,而每个角就是二维平面的一个点具有x和y属性,4个点的x,y间接保存到df1到df8变量中。

      注意cvCloneImage函数和cvCopyImage函数的区别,前来可用来分配内存,后者不负责内存分配,只负责值的传递。这个代码不包含图像的放大、缩小、旋转功能,不过如果愿意的话,完全可以用例子中的函数自己写这些功能,因为放大、缩小、旋转图像不过是任意变换图像四个角的特例。

 

     再来个自己写的仿射变换代码:

[cpp]  view plain copy
  1. //仿射变换  
  2. #include <cv.h>  
  3. #include <highgui.h>  
  4.   
  5. int main(int argc,char** argv)  
  6. {  
  7.     CvPoint2D32f srcTri[3],dstTri[3];  
  8.     CvMat* rot_mat = cvCreateMat(2,3,CV_32FC1);  
  9.     CvMat* warp_mat = cvCreateMat(2,3,CV_32FC1);  
  10.     IplImage *src,*dst, *srcBak;  
  11.     //int df1(0),df2(33),df3(85),df4(25),df5(15),df6(70);  
  12.     int df1(0),df2(0),df3(0),df4(0),df5(0),df6(0);  
  13.     double angle(-50.0),scale(0.6);  
  14.     float delta = 0.01;  
  15.     int pressKey;  
  16.   
  17.     if(!(src=cvLoadImage("../ac.jpg",1)) )  
  18.     {  
  19.         return -1;  
  20.     }  
  21.     srcTri[0].x = 0;  
  22.     srcTri[0].y = 0;  
  23.     srcTri[1].x = src->width-1;  
  24.     srcTri[1].y = 0;  
  25.     srcTri[2].x = 0;  
  26.     srcTri[2].y = src->height-1;  
  27.     dst = cvCloneImage(src);  
  28.     srcBak = cvCloneImage(src);  
  29.     cvCopy(src,srcBak);  
  30.     dst->origin = src->origin;  
  31.     cvZero(dst);  
  32.     cvNamedWindow("at",1);  
  33.     CvFont font = cvFont(1,1);  
  34.   
  35.     while(1)  
  36.     {  
  37.         dstTri[0].x = srcBak->width*delta*(df1%101);  
  38.         dstTri[0].y = srcBak->height*delta*(df2%101);  
  39.         dstTri[1].x = src->width-1 + srcBak->width*delta*(df3%101);  
  40.         dstTri[1].y = srcBak->height*delta*(df4%101);  
  41.         dstTri[2].x = srcBak->width*delta*(df5%101);  
  42.         dstTri[2].y = src->height-1 + srcBak->height*delta*(df6%101);  
  43.           
  44.         cvGetAffineTransform(srcTri,dstTri,warp_mat);  
  45.         cvWarpAffine(srcBak,dst,warp_mat);  
  46.         cvCopy(dst,src);  
  47.         //compute rotation matrix  
  48.         CvPoint2D32f center = cvPoint2D32f(src->width/2,src->height/2);  
  49.         cv2DRotationMatrix(center,angle,scale,rot_mat);  
  50.         //do the transformation  
  51.         cvWarpAffine(src,dst,rot_mat);  
  52.         //--------------------------字符显示-----------------------------------------  
  53.         char buf[8];  
  54.         char dspStr1[32] = {'/0'};  //  
  55.         char dspStr2[32] = {'/0'};  //  
  56.         char dspStr3[32] = {'/0'};  //  
  57.   
  58.         memset(buf,'/0',sizeof(buf));  
  59.         strcat(dspStr1,"|");  
  60.         strcat(dspStr1,itoa(df4%101,buf,10));  
  61.         strcat(dspStr1,",");  
  62.         strcat(dspStr1,itoa(df5%101,buf,10));  
  63.         strcat(dspStr1,",");  
  64.         strcat(dspStr1,itoa(df6%101,buf,10));  
  65.         strcat(dspStr1,"|");  
  66.   
  67.         strcat(dspStr2,"|angle=");  
  68.         strcat(dspStr2,itoa(int(angle),buf,10));  
  69.         strcat(dspStr2,",scale=");  
  70.         strcat(dspStr2,itoa(int(scale*100),buf,10));  
  71.         strcat(dspStr2,"%|");  
  72.         //「」┌└┘┐|  
  73.         strcat(dspStr3,"|");  
  74.         strcat(dspStr3,itoa(df1%101,buf,10));  
  75.         strcat(dspStr3,",");  
  76.         strcat(dspStr3,itoa(df2%101,buf,10));  
  77.         strcat(dspStr3,",");  
  78.         strcat(dspStr3,itoa(df3%101,buf,10));  
  79.         strcat(dspStr3,"|");  
  80.         cvPutText(dst,dspStr1,cvPoint(dst->width-120,20),&font,cvScalar(0,0xff));  
  81.         cvPutText(dst,dspStr2,cvPoint(dst->width-210,40),&font,cvScalar(0,0xff));  
  82.         cvPutText(dst,dspStr3,cvPoint(dst->width-120,60),&font,cvScalar(0,0xff));  
  83.         //-------------------------------------------------------------------------------------  
  84.         cvShowImage("at",dst);  
  85.         pressKey = cvWaitKey();  
  86.     //  printf("src->width:%d/n",src->width);  
  87.         printf("%c pressed/n",pressKey);  
  88.         switch(pressKey)  
  89.         {  
  90.         case '1':  
  91.             df1++;  
  92.             break;  
  93.         case 0x230000:  
  94.             df1--;  
  95.             break;  
  96.         case '2':  
  97.             df2++;  
  98.             break;  
  99.         case 0x280000:  
  100.             df2--;  
  101.             break;  
  102.         case '3':  
  103.             df3++;  
  104.             break;  
  105.         case 0x220000:  
  106.             df3--;  
  107.             break;  
  108.         case '4':   //旋转角度  
  109.             angle++;  
  110.             break;  
  111.         case 0x250000:  
  112.             angle--;  
  113.             break;  
  114.         case '6':   //缩放  
  115.             scale+=0.01;  
  116.             break;  
  117.         case 0x270000:  
  118.             scale-=0.01;  
  119.             break;  
  120.         case '7':  
  121.             df4++;  
  122.             break;  
  123.         case 0x240000:  
  124.             df4--;  
  125.             break;  
  126.         case '8':  
  127.             df5++;  
  128.             break;  
  129.         case 0x260000:  
  130.             df5--;  
  131.             break;  
  132.         case '9':  
  133.             df6++;  
  134.             break;  
  135.         case 0x210000:  
  136.             df6--;  
  137.             break;  
  138.         case 27:  
  139.             cvReleaseImage(&dst);  
  140.             cvDestroyWindow("at");  
  141.             cvReleaseMat(&rot_mat);  
  142.             cvReleaseMat(&warp_mat);  
  143.             return 0;  
  144.         default:break;  
  145.         }  
  146.     }  
  147.   
  148.     cvReleaseImage(&dst);  
  149.     cvReleaseMat(&rot_mat);  
  150.     cvReleaseMat(&warp_mat);  
  151.     return 0;  
  152. }  

      这个程序中加入图片的放大、缩小、旋转功能,另外仿射变换也是透视变换的一个特例,因为仿射变换过程中图像始终是平行四边形的。所以要确定仿射变换的目标图像,只需要三个点的坐标,因为三个点可以确定一个平行四边形,比透视变换少一个点的坐标。

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值