【练习4.7】使用键盘控制透视变换和仿射变换的变换矩阵:实现拉伸、收缩、扭曲、旋转

《学习OpenCV》中文版第4章第7题

 注意:操作的使用将输入法状态切换到“英文”状态

提纲
题目要求
程序代码
结果图片

 

 

 

 

题目要求:

a、使用数字键1~9以及数字键与Shift的组合,实现透视变换变换矩阵中对应元素的增大和缩小

b、使用上下方向键实现仿射变换变换矩阵中对应元素的增大和缩小,以实现对图片的缩放。

c、使用左右方向键实现仿射变换变换矩阵中对应元素的增大和缩小,以实现对图片的旋转。

程序代码:

  1 #include "stdafx.h"
  2 #include <cv.h>
  3 #include <highgui.h>
  4 #include <iostream>
  5 using namespace cv;
  6 using namespace std;
  7 //函数声明-->--->-->--->-->--->-->--->//
  8 
  9 int shiftKeyHandler(int key);
 10 
 11 //<--<--<--<--<--<--<--<--<--函数声明//
 12 
 13 int _tmain(int argc, _TCHAR* argv[])
 14 {
 15     const char * fileName = "D:\\Work\\Work_Programming\\Source\\Image\\lena.jpg";
 16     IplImage * img = cvLoadImage(fileName, CV_LOAD_IMAGE_UNCHANGED);    
 17     assert(img);
 18     
 19     IplImage * dst = cvCloneImage(img);
 20     dst->origin = img->origin;
 21     cvZero(dst);
 22 
 23     IplImage * affinedImage = NULL;
 24     CvPoint2D32f center = cvPoint2D32f(img->width / 2, img->height/2);
 25     double angle = -20.0;
 26     double scale = 1.0;    
 27 
 28     cvNamedWindow("ExerciseWindow", CV_WINDOW_AUTOSIZE);    
 29     cvNamedWindow("透视变换", CV_WINDOW_AUTOSIZE);
 30     cvNamedWindow("图片缩放旋转", CV_WINDOW_AUTOSIZE);
 31 
 32     cvShowImage("ExerciseWindow", img);
 33 
 34     CvMat * warp_matrix = cvCreateMatHeader(3, 3, CV_32FC1);     
 35     float matDataSource[9] = { 0.372190326f, 0.216031685f, 25.6000004f,
 36         -0.213343531f, 0.600807548f, 168.960007f,
 37         -0.00104052317f, 0.000641974097f, 1.00000000f };
 38     warp_matrix->data.fl = matDataSource;
 39     
 40     CvMat *rot_mat = cvCreateMat(2, 3, CV_32FC1);
 41 
 42     while (true)
 43     { 
 44         int key = cvWaitKey(0);
 45         
 46         //---------------------------透视变换:开始--------------------------------//
 47         //使用1~9键盘数字或与Shift的结合控制透视变换矩阵的9个元素
 48 
 49         //当没有按下Shift键的时候
 50         if (key >= 49 && key <= 57)    //按键1~9的ASCII码是49~57
 51         {
 52             matDataSource[key % 49] += matDataSource[key % 49] / 10.0f;    //这种方式可以省掉使用switch的大段代码
 53         }
 54         else//当按下Shift键的时候
 55         {
 56             if (key == 27)
 57             {
 58                 break;
 59             }
 60 
 61             int subscript = shiftKeyHandler(key);
 62             if (subscript != -1)
 63             {
 64                 //题目要求是对应数据最小值是0,但实际操作中发现,有负值的情况比较理想
 65                 /*float temp = matDataSource[subscript] / 10.0f;
 66                 if ((matDataSource[subscript] -= matDataSource[subscript] / 10.0f) < 0.000001f)
 67                 {
 68                     matDataSource[subscript] += temp;
 69                 }*/
 70 
 71                 matDataSource[subscript] -= matDataSource[subscript] / 10.0f;
 72             }
 73             else
 74             {
 75                 cout << "请在程序获取输入焦点的情况下将输入法切换到英文状态再试!" << endl;
 76             }
 77         }
 78 
 79         cvWarpPerspective(img, dst, warp_matrix);
 80         cvShowImage("透视变换", dst);
 81 
 82         //---------------------------透视变换:结束--------------------------------//        
 83 
 84         //---------------------------图片缩放与旋转:开始(仿射变换方法)----------------//
 85         //使用上下箭头即“↑”“↓”控制图片放大缩小
 86         //使用上下箭头即“←”“→”控制图片旋转
 87 
 88         if (key == 2490368 || key == 2621440 || key == 2424832 || key == 2555904)
 89         {
 90             affinedImage = cvCloneImage(img);
 91             affinedImage->origin = img->origin;
 92             cvZero(affinedImage);
 93             
 94             if (key == 2490368)//方向键“↑”
 95             {
 96                 scale += scale*0.2;
 97             }
 98 
 99             if (key == 2621440)
100             {
101                 scale -= scale*0.2;
102             }
103 
104             if (key == 2424832)//方向键“←”
105             {
106                 angle -= 10.0;
107             }
108 
109             if (key == 2555904)
110             {
111                 angle += 10.0;
112             }
113 
114             cv2DRotationMatrix(center, angle, scale, rot_mat);
115             cvWarpAffine(img, affinedImage, rot_mat);
116             cvShowImage("图片缩放旋转", affinedImage);
117         }
118         else if (key == 27)
119         {
120             break;
121         }
122 
123         //---------------------------图片缩放与旋转:结束--------------------------------//    
124     }
125 
126     //cvWaitKey(0);
127 
128     cvReleaseImage(&img);
129     cvReleaseImage(&dst);
130     cvReleaseImage(&affinedImage);
131     cvDestroyWindow("ExerciseWindow");     
132     cvDestroyWindow("透视变换");
133     cvDestroyWindow("图片缩放旋转");
134 
135     return 0;
136 }
137 
138 //当同时按下Shift键时,处理key的值,使其结果方便使用
139 int shiftKeyHandler(int key)
140 {
141     //输入法分为英文和中文两种输入状态,本程序只开了英文状态,当然,实际开发中也可在使用代码控制输入法状态
142     switch (key)
143     {
144     case '!':return 0;
145     case '@':return 1;
146     case '#':return 2;
147     case '$':return 3;
148     case '%':return 4;
149     case '^':return 5;
150     case '&':return 6;
151     case '*':return 7;
152     case '(':return 8;
153     default:
154         return -1;        
155     }    
156 }

 

结果图片

 

 

posted on 2014-08-03 18:03  毋忆典藏  阅读(630)  评论(0编辑  收藏  举报