《学习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.\texit\n");

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

你可能感兴趣的:(opencv)