zoukankan      html  css  js  c++  java
  • 《学习OpenCV》练习题第四章第七题abc

    题外话:一直是打算把这本书的全部课后编程题写完的,中间断了几个月,一直忙于其他事。现在开始补上。

    这道题我不清楚我理解的题意是不是正确的,这道题可以练习用OpenCV实现透视变换(可以用于矫正在3维环境下的图像失真),b&c部分则是实现图像放大缩小插值,旋转图像。所有的功能都和键盘事件处理联系起来,纯OpenCV实现,和OS无关。不过,在处理SHIFT键时,我取得是其在键盘上对应字符的ASCII码,好像OpenCV对键盘事件的支持不如对鼠标事件的支持。所以SHIFT键+小键盘上的数字键是不行的。

    代码:

      1 #include <opencv/highgui.h>
      2 #include <opencv/cv.h>
      3 #include <opencv_libs.h>
      4 
      5 /*
      6  *《学习OpenCV》第四章第七题  
      7  * 完成时间:0:23 10/4 星期五 2013  
      8  */    
      9 
     10 #define   WARPSTEPSIZE     0.01      // 透视变换矩阵每次的变化率
     11 
     12 #define   RESIZESTEPSIZE   0.1       // 放大、缩小每次的变化率
     13 
     14 #define   ROTATESTEPSIZE   10        // 旋转图像时每次旋转的角度(逆时针)
     15 
     16 // 透视变换目标变换矩阵
     17 CvPoint2D32f g_dstQuad[4];
     18 
     19 // image width & height
     20 int g_width = 0;
     21 int g_height = 0;
     22 
     23 // rotate degree
     24 int g_RotateDegree = 0;  
     25 
     26 /*
     27  * function: Zoom in or zoom out an image.
     28  * param: inorout -- indicate in or out(0 means zoom in; 1 means zoom out)
     29  * param: the destination size.
     30  */
     31 CvSize getZoomDstSize(int inorout)
     32 {
     33     if(inorout != 0 && inorout != 1)
     34     {
     35         return cvSize(-1, -1);
     36     }
     37     if(g_height == 0 || g_width == 0)
     38     {
     39         return cvSize(-1, -1);
     40     }
     41 
     42     // Zoom in
     43     if(inorout == 0)
     44     {
     45         g_width += g_width * RESIZESTEPSIZE;
     46         g_height += g_height * RESIZESTEPSIZE;
     47     }
     48     else if(inorout == 1)
     49     {
     50         g_width -= g_width * RESIZESTEPSIZE;
     51         g_height -= g_height * RESIZESTEPSIZE;
     52 
     53         if(g_height < 1)
     54         {
     55             g_height = 1;
     56         }
     57         else if(g_width < 1)
     58         {
     59             g_width = 1;
     60         }
     61     }
     62 
     63     return cvSize(g_width, g_height);
     64 }
     65 
     66 void rotateImage(IplImage* img, IplImage *img_rotate,float degree)  
     67 {  
     68     // 旋转中心
     69     CvPoint2D32f center;    
     70     center.x=float (img->width/2.0+0.5);  
     71     center.y=float (img->height/2.0+0.5);  
     72     // 计算二维旋转的仿射变换矩阵  
     73     float m[6];              
     74     CvMat M = cvMat( 2, 3, CV_32F, m );  
     75     cv2DRotationMatrix( center, degree,1, &M);  
     76     // 变换图像,并用黑色填充其余值  
     77     cvWarpAffine(img,img_rotate, &M,CV_INTER_LINEAR+CV_WARP_FILL_OUTLIERS,cvScalarAll(0) );  
     78 } 
     79 
     80 /*
     81  * function: change the g_dstQuad(minus or plus one of the element)
     82  * param: index -- which element(0 -- 4)
     83  * param: xory -- indicate x or y to change(0 means x; 1 means y)
     84  * param: operation -- indicate which operation(0 means plus; 1 means minus) 
     85  * return: 0 means success.  -1 means failed.
     86  */
     87 int changeg_dstQuad(int index, int xory, int operation)
     88 {
     89     // param check
     90     if( index > 3 || index < 0 || 
     91         (xory != 0 && xory != 1) ||
     92         (operation != 0 && operation != 1) ||
     93         g_width == 0 || g_height == 0)
     94     {
     95         return -1;
     96     }
     97 
     98     // plus
     99     if(operation == 0)
    100     {
    101         if(xory == 0)    // x
    102         {
    103             g_dstQuad[index].x += WARPSTEPSIZE * g_width;
    104             if(g_dstQuad[index].x > g_width - 1)
    105             {
    106                 g_dstQuad[index].x = g_width - 1;
    107             }
    108         }
    109         else if(xory == 1)   // y
    110         {
    111             g_dstQuad[index].y += WARPSTEPSIZE * g_height;
    112             if(g_dstQuad[index].y > g_height - 1)
    113             {
    114                 g_dstQuad[index].y = g_height -1;
    115             }
    116         }
    117     }
    118     
    119     // minus
    120     else if (operation == 1)
    121     {
    122         if(xory == 0)        // x
    123         {
    124             g_dstQuad[index].x -= WARPSTEPSIZE * g_width;
    125             if(g_dstQuad[index].x < 0)
    126             {
    127                 g_dstQuad[index].x = 0;
    128             }
    129         }
    130         else if(xory == 1 )   // y
    131         {
    132             g_dstQuad[index].y -= WARPSTEPSIZE * g_height;
    133             if(g_dstQuad[index].y < 0)
    134             {
    135                 g_dstQuad[index].y = 0;
    136             }
    137         }
    138     }
    139 
    140     return 0;
    141 }
    142 
    143 int main()
    144 {
    145     const char * FILEPATH = "lena.bmp";
    146     IplImage * src = cvLoadImage(FILEPATH, CV_LOAD_IMAGE_UNCHANGED);
    147 
    148     if(!src)
    149     {
    150         printf("load image error.	exit
    ");
    151         return -1;
    152     }
    153 
    154     CvPoint2D32f srcQuad[4];
    155     CvMat* warp_matrix = cvCreateMat(3, 3, CV_32FC1);
    156     IplImage *dst;
    157 
    158     cvNamedWindow("Source_Image", 1);
    159     cvNamedWindow("Perspective_Warp", 1);
    160 
    161     dst = cvCloneImage(src);
    162     dst->origin = dst->origin;
    163     cvZero(dst);
    164 
    165     // image width & height
    166     g_width = src->width;
    167     g_height = src->height;
    168 
    169     srcQuad[0].x = 0;               // src Top left
    170     srcQuad[0].y = 0;
    171     srcQuad[1].x = g_width - 1;   // src Top right
    172     srcQuad[1].y = 0;
    173     srcQuad[2].x = 0;                // src Bottom left
    174     srcQuad[2].y = g_height - 1;  
    175     srcQuad[3].x = g_width - 1;     // src Bottom right
    176     srcQuad[3].y = g_height - 1;
    177 
    178     g_dstQuad[0].x = 0;           // dst Top left
    179     g_dstQuad[0].y = 0;
    180     g_dstQuad[1].x = g_width - 1;   // dst Top right
    181     g_dstQuad[1].y = 0;
    182     g_dstQuad[2].x = 0;           // dst Bottom left
    183     g_dstQuad[2].y = g_height - 1;
    184     g_dstQuad[3].x = g_width - 1;   // dst Bottom right
    185     g_dstQuad[3].y = g_height - 1;
    186 
    187     while(1)
    188     {
    189         cvShowImage("Source_Image", src);
    190         char c = cvWaitKey(10);
    191        
    192         int ret = 0;
    193         switch(c)
    194         {
    195         // ESC
    196         case 27:
    197             goto end;
    198             break;
    199         // 0 -- 放大图像
    200         case 48:
    201             {
    202                 cvNamedWindow("Resize", 1);
    203                 CvSize dstSize = getZoomDstSize(0);
    204                 if(dstSize.height == -1 || dstSize.width == -1)
    205                 {
    206                     goto end;
    207                 }
    208 
    209                 IplImage* imageresize = cvCreateImage(dstSize, src->depth, src->nChannels);
    210                 if(!imageresize)
    211                 {
    212                     goto end;
    213                 }
    214                 cvResize(src, imageresize, CV_INTER_LINEAR);
    215                 cvShowImage("Resize", imageresize);
    216                 cvReleaseImage(&imageresize);
    217             }
    218             break;
    219         // SHIFT + 0 ')' -- 缩小图像
    220         case 41:
    221             {
    222                 cvNamedWindow("Resize", 1);
    223                 CvSize dstSize = getZoomDstSize(1);
    224                 if(dstSize.height == -1 || dstSize.width == -1)
    225                 {
    226                     goto end;
    227                 }
    228 
    229                 IplImage* imageresize = cvCreateImage(dstSize, src->depth, src->nChannels);
    230                 if(!imageresize)
    231                 {
    232                     goto end;
    233                 }
    234                 cvResize(src, imageresize, CV_INTER_LINEAR);
    235                 cvShowImage("Resize", imageresize);
    236                 cvReleaseImage(&imageresize);
    237             }
    238             break;
    239         // 9 -- 旋转图像(逆时针)
    240         case 57:
    241             {
    242                 cvNamedWindow("Rotate", 1);
    243                 
    244                 IplImage* imagerotate = cvCreateImage(cvGetSize(src), src->depth, src->nChannels);
    245                 if(!imagerotate)
    246                 {
    247                     goto end;
    248                 }
    249                 g_RotateDegree += ROTATESTEPSIZE;
    250                 rotateImage(src, imagerotate, g_RotateDegree);
    251                 cvShowImage("Rotate", imagerotate);
    252                 cvReleaseImage(&imagerotate);
    253             }
    254             break;
    255         // SHIFT + 9 '(' -- 旋转图像(顺时针)
    256         case 40:
    257             {
    258                 cvNamedWindow("Rotate", 1);
    259 
    260                 IplImage* imagerotate = cvCreateImage(cvGetSize(src), src->depth, src->nChannels);
    261                 if(!imagerotate)
    262                 {
    263                     goto end;
    264                 }
    265                 g_RotateDegree -= ROTATESTEPSIZE;
    266                 rotateImage(src, imagerotate, g_RotateDegree);
    267                 cvShowImage("Rotate", imagerotate);
    268                 cvReleaseImage(&imagerotate);
    269             }
    270             break;
    271         // 1
    272         case 49:
    273             ret = changeg_dstQuad(0, 0, 0);
    274             break;
    275         // 2
    276         case 50:
    277             ret = changeg_dstQuad(0, 1, 0);
    278             break;
    279         // 3
    280         case 51:
    281             ret = changeg_dstQuad(1, 0, 0);
    282             break;
    283         // 4
    284         case 52:
    285             ret = changeg_dstQuad(1, 1, 0);
    286             break;
    287         // 5
    288         case 53:
    289             ret = changeg_dstQuad(2, 0, 0);
    290             break;
    291         // 6
    292         case 54:
    293             ret = changeg_dstQuad(2, 1, 0);
    294             break;
    295         // 7
    296         case 55:
    297             ret = changeg_dstQuad(3, 0, 0);
    298             break;
    299         // 8
    300         case 56:
    301             ret = changeg_dstQuad(3, 1, 0);
    302             break;
    303         // SHIFT + 1  '!'
    304         case 33:
    305             ret = changeg_dstQuad(0, 0, 1);
    306             break;
    307         // SHIFT + 2  '@'
    308         case 64:
    309             ret = changeg_dstQuad(0, 1, 1);
    310             break;
    311         // SHIFT + 3 '#'
    312         case 35:
    313             ret = changeg_dstQuad(1, 0, 1);
    314             break;
    315         // SHIFT + 4 '$'
    316         case 36:
    317             ret = changeg_dstQuad(1, 1, 1);
    318             break;
    319         // SHIFT + 5 '%'
    320         case 37:
    321             ret = changeg_dstQuad(2, 0, 1);
    322             break;
    323         // SHIFT + 6 '^'
    324         case 94:
    325             ret = changeg_dstQuad(2, 1, 1);
    326             break;
    327         // SHIFT + 7 '&'
    328         case 38:
    329             ret = changeg_dstQuad(3, 0, 1);
    330             break;
    331         // SHIFT + 8 '*'
    332         case 42:
    333             ret = changeg_dstQuad(3, 1, 1);
    334             break;
    335 
    336         default:
    337             break;
    338         }
    339 
    340         // Error
    341         if(ret != 0)
    342         {
    343             goto end;
    344         }
    345         cvGetPerspectiveTransform(srcQuad, g_dstQuad, warp_matrix);
    346         cvWarpPerspective( src, dst, warp_matrix, 
    347                            CV_INTER_LINEAR + CV_WARP_FILL_OUTLIERS, cvScalarAll(0));
    348 
    349         cvShowImage("Source_Image", src);
    350         cvShowImage("Perspective_Warp", dst);
    351     }
    352 
    353 end:
    354     cvReleaseImage(&src);
    355     cvReleaseImage(&dst);
    356     cvReleaseMat(&warp_matrix);
    357     cvDestroyAllWindows();
    358 
    359     return 0;
    360 }

    程序运行截图:

    首先是透视变换:

    图像放大缩小(b部分):

    图像旋转(c部分):

  • 相关阅读:
    redis配置文件 redis.conf
    CentOS安装 NodeJS 和 NPM
    Docker中运行redis报错误: Failed opening the RDB file root (in server root dir /etc/cron.d) for saving: Permission denied
    AllowControlAllowOrigin:谷歌跨域扩展插件下载
    uniapp 判断客户端环境是安卓还是ios
    Windows环境下查看某个端口被哪个应用程序占用并停止程序
    Oracle数据库快速入门
    Linux 使用vim命令编辑文件内容
    解决VMware Workstation客户机与宿主机无法复制文件和共享剪切板的问题
    Spring 中的事件机制 ApplicationEventPublisher
  • 原文地址:https://www.cnblogs.com/qdsclove/p/3351171.html
Copyright © 2011-2022 走看看