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

原文地址:https://www.cnblogs.com/qdsclove/p/3351171.html