• 《学习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部分):

  • 相关阅读:
    linux 内核定时器 timer_list详解
    linux2.6源码分析之解压内核映像 head.s
    [C#]我自己写的一个对字节中每位进行修改值的函数
    Android Intent调用大全
    proguard 原理
    何为夫妻?何为家?何为幸福?
    生命只是瞬间,而有些人终究是过客?(转)
    bind端口复用
    在android开发中应该如何管理内存或者是在开发过程中应该注意哪些问题来较少OOM?
    W/ActivityManager( 1419): Activity is launching as a new task, so cancelling activity result.
  • 原文地址:https://www.cnblogs.com/qdsclove/p/3351171.html
Copyright © 2020-2023  润新知