《学习OpenCV》练习题第四章第七题abc

51132 ワード

余談:ずっとこの本のすべての授業の後でプログラミングの問題を書き終えるつもりで、途中で数ヶ月切れて、ずっと他のことで忙しいです.今から補充します.
この問題は私が理解している問題の意味が正しいかどうか分かりません.この問題はOpenCVで透視変換(3次元環境での画像歪みを矯正するのに使用できる)を練習することができ、b&c部分は画像拡大縮小補間を実現し、画像を回転することができます.すべての機能はキーボードイベント処理に関連しており,OSとは無関係に純粋なOpenCVが実現されている.ただし、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.\texit
"); 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部分):