题外话:一直是打算把这本书的全部课后编程题写完的,中间断了几个月,一直忙于其他事。现在开始补上。

这道题我不清楚我理解的题意是不是正确的,这道题可以练习用OpenCV实现透视变换(可以用于矫正在3维环境下的图像失真),b&c部分则是实现图像放大缩小插值,旋转图像。所有的功能都和键盘事件处理联系起来,纯OpenCV实现,和OS无关。不过,在处理SHIFT键时,我取得是其在键盘上对应字符的ASCII码,好像OpenCV对键盘事件的支持不如对鼠标事件的支持。所以SHIFT键+小键盘上的数字键是不行的。

代码:

 #include <opencv/highgui.h>
#include <opencv/cv.h>
#include <opencv_libs.h> /*
*《学习OpenCV》第四章第七题
* 完成时间:0:23 10/4 星期五 2013
*/ #define WARPSTEPSIZE 0.01 // 透视变换矩阵每次的变化率 #define RESIZESTEPSIZE 0.1 // 放大、缩小每次的变化率 #define ROTATESTEPSIZE 10 // 旋转图像时每次旋转的角度(逆时针) // 透视变换目标变换矩阵
CvPoint2D32f g_dstQuad[]; // image width & height
int g_width = ;
int g_height = ; // rotate degree
int g_RotateDegree = ; /*
* function: Zoom in or zoom out an image.
* param: inorout -- indicate in or out(0 means zoom in; 1 means zoom out)
* param: the destination size.
*/
CvSize getZoomDstSize(int inorout)
{
if(inorout != && inorout != )
{
return cvSize(-, -);
}
if(g_height == || g_width == )
{
return cvSize(-, -);
} // Zoom in
if(inorout == )
{
g_width += g_width * RESIZESTEPSIZE;
g_height += g_height * RESIZESTEPSIZE;
}
else if(inorout == )
{
g_width -= g_width * RESIZESTEPSIZE;
g_height -= g_height * RESIZESTEPSIZE; if(g_height < )
{
g_height = ;
}
else if(g_width < )
{
g_width = ;
}
} return cvSize(g_width, g_height);
} void rotateImage(IplImage* img, IplImage *img_rotate,float degree)
{
// 旋转中心
CvPoint2D32f center;
center.x=float (img->width/2.0+0.5);
center.y=float (img->height/2.0+0.5);
// 计算二维旋转的仿射变换矩阵
float m[];
CvMat M = cvMat( , , CV_32F, m );
cv2DRotationMatrix( center, degree,, &M);
// 变换图像,并用黑色填充其余值
cvWarpAffine(img,img_rotate, &M,CV_INTER_LINEAR+CV_WARP_FILL_OUTLIERS,cvScalarAll() );
} /*
* function: change the g_dstQuad(minus or plus one of the element)
* param: index -- which element(0 -- 4)
* param: xory -- indicate x or y to change(0 means x; 1 means y)
* param: operation -- indicate which operation(0 means plus; 1 means minus)
* return: 0 means success. -1 means failed.
*/
int changeg_dstQuad(int index, int xory, int operation)
{
// param check
if( index > || index < ||
(xory != && xory != ) ||
(operation != && operation != ) ||
g_width == || g_height == )
{
return -;
} // plus
if(operation == )
{
if(xory == ) // x
{
g_dstQuad[index].x += WARPSTEPSIZE * g_width;
if(g_dstQuad[index].x > g_width - )
{
g_dstQuad[index].x = g_width - ;
}
}
else if(xory == ) // y
{
g_dstQuad[index].y += WARPSTEPSIZE * g_height;
if(g_dstQuad[index].y > g_height - )
{
g_dstQuad[index].y = g_height -;
}
}
} // minus
else if (operation == )
{
if(xory == ) // x
{
g_dstQuad[index].x -= WARPSTEPSIZE * g_width;
if(g_dstQuad[index].x < )
{
g_dstQuad[index].x = ;
}
}
else if(xory == ) // y
{
g_dstQuad[index].y -= WARPSTEPSIZE * g_height;
if(g_dstQuad[index].y < )
{
g_dstQuad[index].y = ;
}
}
} return ;
} int main()
{
const char * FILEPATH = "lena.bmp";
IplImage * src = cvLoadImage(FILEPATH, CV_LOAD_IMAGE_UNCHANGED); if(!src)
{
printf("load image error.\texit\n");
return -;
} CvPoint2D32f srcQuad[];
CvMat* warp_matrix = cvCreateMat(, , CV_32FC1);
IplImage *dst; cvNamedWindow("Source_Image", );
cvNamedWindow("Perspective_Warp", ); dst = cvCloneImage(src);
dst->origin = dst->origin;
cvZero(dst); // image width & height
g_width = src->width;
g_height = src->height; srcQuad[].x = ; // src Top left
srcQuad[].y = ;
srcQuad[].x = g_width - ; // src Top right
srcQuad[].y = ;
srcQuad[].x = ; // src Bottom left
srcQuad[].y = g_height - ;
srcQuad[].x = g_width - ; // src Bottom right
srcQuad[].y = g_height - ; g_dstQuad[].x = ; // dst Top left
g_dstQuad[].y = ;
g_dstQuad[].x = g_width - ; // dst Top right
g_dstQuad[].y = ;
g_dstQuad[].x = ; // dst Bottom left
g_dstQuad[].y = g_height - ;
g_dstQuad[].x = g_width - ; // dst Bottom right
g_dstQuad[].y = g_height - ; while()
{
cvShowImage("Source_Image", src);
char c = cvWaitKey(); int ret = ;
switch(c)
{
// ESC
case :
goto end;
break;
// 0 -- 放大图像
case :
{
cvNamedWindow("Resize", );
CvSize dstSize = getZoomDstSize();
if(dstSize.height == - || dstSize.width == -)
{
goto end;
} IplImage* imageresize = cvCreateImage(dstSize, src->depth, src->nChannels);
if(!imageresize)
{
goto end;
}
cvResize(src, imageresize, CV_INTER_LINEAR);
cvShowImage("Resize", imageresize);
cvReleaseImage(&imageresize);
}
break;
// SHIFT + 0 ')' -- 缩小图像
case :
{
cvNamedWindow("Resize", );
CvSize dstSize = getZoomDstSize();
if(dstSize.height == - || dstSize.width == -)
{
goto end;
} IplImage* imageresize = cvCreateImage(dstSize, src->depth, src->nChannels);
if(!imageresize)
{
goto end;
}
cvResize(src, imageresize, CV_INTER_LINEAR);
cvShowImage("Resize", imageresize);
cvReleaseImage(&imageresize);
}
break;
// 9 -- 旋转图像(逆时针)
case :
{
cvNamedWindow("Rotate", ); IplImage* imagerotate = cvCreateImage(cvGetSize(src), src->depth, src->nChannels);
if(!imagerotate)
{
goto end;
}
g_RotateDegree += ROTATESTEPSIZE;
rotateImage(src, imagerotate, g_RotateDegree);
cvShowImage("Rotate", imagerotate);
cvReleaseImage(&imagerotate);
}
break;
// SHIFT + 9 '(' -- 旋转图像(顺时针)
case :
{
cvNamedWindow("Rotate", ); IplImage* imagerotate = cvCreateImage(cvGetSize(src), src->depth, src->nChannels);
if(!imagerotate)
{
goto end;
}
g_RotateDegree -= ROTATESTEPSIZE;
rotateImage(src, imagerotate, g_RotateDegree);
cvShowImage("Rotate", imagerotate);
cvReleaseImage(&imagerotate);
}
break;
//
case :
ret = changeg_dstQuad(, , );
break;
//
case :
ret = changeg_dstQuad(, , );
break;
//
case :
ret = changeg_dstQuad(, , );
break;
//
case :
ret = changeg_dstQuad(, , );
break;
//
case :
ret = changeg_dstQuad(, , );
break;
//
case :
ret = changeg_dstQuad(, , );
break;
//
case :
ret = changeg_dstQuad(, , );
break;
//
case :
ret = changeg_dstQuad(, , );
break;
// SHIFT + 1 '!'
case :
ret = changeg_dstQuad(, , );
break;
// SHIFT + 2 '@'
case :
ret = changeg_dstQuad(, , );
break;
// SHIFT + 3 '#'
case :
ret = changeg_dstQuad(, , );
break;
// SHIFT + 4 '$'
case :
ret = changeg_dstQuad(, , );
break;
// SHIFT + 5 '%'
case :
ret = changeg_dstQuad(, , );
break;
// SHIFT + 6 '^'
case :
ret = changeg_dstQuad(, , );
break;
// SHIFT + 7 '&'
case :
ret = changeg_dstQuad(, , );
break;
// SHIFT + 8 '*'
case :
ret = changeg_dstQuad(, , );
break; default:
break;
} // Error
if(ret != )
{
goto end;
}
cvGetPerspectiveTransform(srcQuad, g_dstQuad, warp_matrix);
cvWarpPerspective( src, dst, warp_matrix,
CV_INTER_LINEAR + CV_WARP_FILL_OUTLIERS, cvScalarAll()); cvShowImage("Source_Image", src);
cvShowImage("Perspective_Warp", dst);
} end:
cvReleaseImage(&src);
cvReleaseImage(&dst);
cvReleaseMat(&warp_matrix);
cvDestroyAllWindows(); return ;
}

程序运行截图:

首先是透视变换:

图像放大缩小(b部分):

图像旋转(c部分):

《学习OpenCV》练习题第四章第七题abc的更多相关文章

  1. 《学习OpenCV》练习题第四章第八题ab

    这道题是利用OpenCV例子程序里自带的人脸检测程序,做点图像的复制操作以及alpha融合. 说明:人脸检测的程序我参照了网上现有的例子程序,没有用我用的OpenCV版本(2.4.5)的facedet ...

  2. 《学习OpenCV》练习题第四章第三题b

    #include <highgui.h> #include <cv.h> #include "opencv_libs.h" /* *<学习OpenCV ...

  3. 《学习OpenCV》练习题第四章第三题a

    #include <highgui.h> #include <cv.h> #include "opencv_libs.h" #pragma comment ...

  4. 《学习OpenCV》 第四章 习题六

    实现的是一个图像标签编辑器,其间遇到了些问题还未解决或者可能解决方法上不是最优,若你有更好的思路可以提供给我,大恩不言谢啦!!☆⌒(*^-゜)v. #include "stdafx.h&qu ...

  5. 《学习OpenCV》练习题第四章第二题

    #include <highgui.h> #include <cv.h> #pragma comment (lib,"opencv_calib3d231d.lib&q ...

  6. 《学习OpenCV》练习题第四章第一题b&c

    #include <highgui.h> #include <cv.h> #pragma comment (lib,"opencv_calib3d231d.lib&q ...

  7. 《学习OpenCV》练习题第四章第一题a

    #include <highgui.h> #include <cv.h> #pragma comment (lib,"opencv_calib3d231d.lib&q ...

  8. Introduction to 3D Game Programming with DirectX 12 学习笔记之 --- 第四章:Direct 3D初始化

    原文:Introduction to 3D Game Programming with DirectX 12 学习笔记之 --- 第四章:Direct 3D初始化 学习目标 对Direct 3D编程在 ...

  9. 学习opencv中文版教程——第二章

    学习opencv中文版教程——第二章 所有案例,跑起来~~~然而并没有都跑起来...我只把我能跑的都尽量跑了,毕竟看书还是很生硬,能运行能出结果,才比较好. 越着急,心越慌,越是着急,越要慢,越是陌生 ...

随机推荐

  1. JAVA网络编程【转】出处不详

    网络编程 网络编程对于很多的初学者来说,都是很向往的一种编程技能,但是很多的初学者却因为很长一段时间无法进入网络编程的大门而放弃了对于该部分技术的学习. 在 学习网络编程以前,很多初学者可能觉得网络编 ...

  2. css中图片的四种地址引用

    URL: CSS中四种引用图片asset的方式:

  3. 【笨嘴拙舌WINDOWS】消息机制

    如果将WINDOWS比做一个人,那么他就是为你提供各种服务的巫师,他手上有各式各样,奇形怪状的奇葩物品.他脑子充满了智慧,能够为你解决你所不能解决的疑难杂症.但是他不认识你! 你从小立志要想考状元,去 ...

  4. 51nod1586 约数和

    果然我自己写的读入优化naive!...换题目给的读入优化就A了...话说用visual交快了好多啊... const int BufferSize=1<<16; char buffer[ ...

  5. BZOJ 1123 BLO

    tarjan求割点计算答案.注意不是每一棵子树都算答案.开个变量记一下. #include<iostream> #include<cstdio> #include<cst ...

  6. (二)win7下用Intelij IDEA 远程调试spark standalone 集群

    关于这个spark的环境搭建了好久,踩了一堆坑,今天 环境: WIN7笔记本  spark 集群(4个虚拟机搭建的) Intelij IDEA15 scala-2.10.4 java-1.7.0 版本 ...

  7. [转载] ubuntu Authentication failure

    ubuntu的root用户默认是禁止的,需要手动打开才行.事实上ubuntu下的所有操作都用不到root用户,由于sudo的合理使用,避免了root用户下误操作而产生的毁灭性问题.root账号启用方法 ...

  8. linux apache 配置fastcgi

    Redhat 上 FastCGI 安装与配置 软件包 相关软件包: httpd 2.2.14      //注意版本 这个版本不会出问题   注:apache httpd安装 fcgi-2.4.0.t ...

  9. GitHub入门:如何上传与下载工程?

    由于经常要在家写代码,所以需要有个能够方便访问代码管理工具.最近尝试了一下GitHub.经过了一翻纠结之后,基本上掌握了他的使用方式.  要使用GitHub需要首先在其网站上进行注册.其官方网站是ht ...

  10. 【转载】HBase基本概念和hbase shell常用命令用法

    1. 简介 HBase是一个分布式的.面向列的开源数据库,源于google的一篇论文<bigtable:一个结构化数据的分布式存储系统>.HBase是Google Bigtable的开源实 ...