图像编程学习笔记5——图像镜像

以下文字内容copy于<<数字图像处理编程入门>>,code为自己实现,是win32控制台程序。

 

镜象(mirror)分水平镜象和垂直镜象两种。图2.2的水平镜象和垂直镜象分别如图2.13和图2.14所示

图2.13   图2.2的水平镜象

                                                                                 

 

图2.14   图2.2的垂直镜象

镜象的变换矩阵很简单。设原图宽为w,高为h,变换后,图的宽和高不变。

水平镜象的变化矩阵为:

                                                                                          

 

(2.10)

垂直镜象的变化矩阵为:

                                                                                          

 

(2.11)

镜象变换的源代码如下,因为和平移的那段程序很类似,程序中的注释就简单一些。

[cpp] view plaincopy

 

    1. /** 
    2. * 程序名: Mirror.cpp 
    3. * 功  能: 实现灰度图像的水平镜像和垂直镜像 
    4. *         测试图片test.bmp放在工程目录下 
    5. */  
    6. #include <iostream>  
    7. #include <windows.h>  
    8. #include <fstream>  
    9. #include <cstring>  
    10. using namespace std;  
    11. BITMAPFILEHEADER bmpFileHeader; //bmp文件头  
    12. BITMAPINFOHEADER bmpInfoHeader; //bmp信息头  
    13. RGBQUAD *pColorTable;       //bmp颜色表  
    14. unsigned char *pBmpData;    //bmp位图数据     
    15. unsigned char *pXBmpData;  //水平镜像bmp位图数据  
    16. unsigned char *pYBmpData;  //垂直镜像bmp位图数据  
    17. /** 
    18. * 函数名: readBmp 
    19. * 参  数: fileName -- 指向文件名的指针 
    20. * 功  能: 读取将要处理的图片的信息,成功返回TRUE 
    21. */  
    22. bool readBmp(char *fileName)  
    23. {  
    24.     FILE *fp = fopen(fileName,"rb");  //以二进制读方式打开  
    25.     if (NULL == fp)  
    26.     {     
    27.         cout<<"open failure!"<<endl;  
    28.         return FALSE;  
    29.     }  
    30.     //获得图片数据  
    31.     fread(&bmpFileHeader,sizeof(BITMAPFILEHEADER),1,fp);  
    32.     fread(&bmpInfoHeader,sizeof(BITMAPINFOHEADER),1,fp);  
    33.     pColorTable = new RGBQUAD[256];  
    34.     fread(pColorTable,sizeof(RGBQUAD),256,fp);  
    35.     int imgSize = bmpInfoHeader.biSizeImage;  
    36.     pBmpData = new unsigned char[imgSize];  
    37.     //因为大小没有改变,所以一起处理了  
    38.     pXBmpData = new unsigned char[imgSize];  
    39.     pYBmpData = new unsigned char[imgSize];  
    40.     fread(pBmpData,sizeof(unsigned char),imgSize,fp);  
    41.     fclose(fp); //关闭文件  
    42.     return TRUE;  
    43. }  
    44. /** 
    45. * 函数名: mirror 
    46. * 功  能: 对图片进行水平和垂直镜像操作 
    47. */  
    48. void mirror()  
    49. {  
    50.     int height = bmpInfoHeader.biHeight;  
    51.     int width = bmpInfoHeader.biWidth;  
    52.     int imgSize = bmpInfoHeader.biSizeImage;  
    53.     memset(pXBmpData,0,sizeof(unsigned char )*imgSize);  
    54.     memset(pYBmpData,0,sizeof(unsigned char )*imgSize);  
    55.     int lineByte = (width * 8 + 31) / 32 * 4;  //每行像素的字节数  
    56.     for(int i = 0; i < height; i++ )  
    57.     {  
    58.         for(int j = 0; j < width; j++ )  
    59.         {  
    60.             *(pXBmpData + i*lineByte + width - 1 - j) = *(pBmpData + i*lineByte + j); //水平镜像  
    61.             *(pYBmpData + (height - i - 1)*lineByte + j) = *(pBmpData + i*lineByte + j);  //垂直镜像  
    62.         }  
    63.     }  
    64. }  
    65. /** 
    66. * 函数名: writeBmp 
    67. * 参  数: fileName -- 处理完之后的bmp图像 
    68. * 功  能: 写入文件数据到相应的文件中 
    69. */  
    70. bool writeBmp(char *fileName,unsigned char *bmpData)  
    71. {  
    72.     FILE *fp = fopen(fileName,"wb"); //以二进制写方式打开  
    73.     if (NULL == fp)  
    74.     {  
    75.         cout<<"open failure!"<<endl;  
    76.         return FALSE;  
    77.     }  
    78.     int imgSize = bmpInfoHeader.biSizeImage;  
    79.     //写入数据  
    80.     fwrite(&bmpFileHeader,sizeof(BITMAPFILEHEADER),1,fp);  
    81.     fwrite(&bmpInfoHeader,sizeof(BITMAPINFOHEADER),1,fp);  
    82.     fwrite(pColorTable,sizeof(RGBQUAD),256,fp);  
    83.     fwrite(bmpData,sizeof(unsigned char),imgSize,fp);  
    84.     fclose(fp);  //关闭文件  
    85.     return TRUE;  
    86. }  
    87. /** 
    88. * 函数名: work 
    89. * 功  能: 主要处理 
    90. */  
    91. void work()  
    92. {  
    93.     char readFileName[] = "test.bmp";  
    94.     if (!readBmp(readFileName))  
    95.     {  
    96.         cout<<"read failure!"<<endl;  
    97.         return ;  
    98.     }  
    99.     mirror();  
    100.     char writeFileNameX[] = "X.bmp";  
    101.     char writeFileNameY[] = "Y.bmp";  
    102.     if (!writeBmp(writeFileNameX,pXBmpData))  
    103.     {  
    104.         cout<<"X write failure!"<<endl;  
    105.         return ;  
    106.     }  
    107.     if (!writeBmp(writeFileNameY,pYBmpData))  
    108.     {  
    109.         cout<<"Y write failure!"<<endl;  
    110.         return ;  
    111.     }  
    112.     //释放  
    113.     delete []pColorTable;  
    114.     delete []pBmpData;  
    115.     delete []pXBmpData;  
    116.     delete []pYBmpData;  
    117.     cout<<"mirror success!"<<endl;  
    118.   
    119. }  
    120. int main()  
    121. {  
    122.     work();  
    123.     return 0;  
    124. }  
时间: 2024-10-29 10:14:10

图像编程学习笔记5——图像镜像的相关文章

图像编程学习笔记8——图像的平滑(去噪)

第一种方法:高斯模版 以下文字内容copy于<<数字图像处理编程入门>>,code为自己实现,是win32控制台程序. 先举个例子说明一下什么是平滑(smoothing),如下面两幅图所示:可以看到,图3.2比图3.1柔和一些(也模糊一些).是不是觉得很神奇?其实实现起来很简单.我们将原图中的每一点的灰度和它周围八个点的灰度相加,然后除以9,作为新图中对应点的灰度,就能实现上面的效果. 这么做并非瞎蒙,而是有其道理的.大概想一想,也很容易明白.举个例子,就象和面一样,先在中间加点水

图像编程学习笔记7——图像缩放

假设放大因子为ratio,(为了避免新图过大或过小,我们在程序中限制0.25≤ratio≤4),缩放(zoom)的变换矩阵很简单: (2.13) 缩放变换的源代码如下,因为和转置的那段程序很类似,程序中的注释就简单一些.   [cpp] view plaincopy   /**  * 函数名: zoom  * 参  数: ratio -- 缩放率  * 功  能: 对图片进行水平和垂直镜像操作  *         只保存原图大小的图像数据,如果没有就用白色填充  */   void zoom(

图像编程学习笔记3——图像旋转

以下文字内容copy于<<数字图像处理编程入门>>,code为自己实现,是win32控制台程序.   旋转(rotation)有一个绕着什么转的问题,通常的做法是以图象的中心为圆心旋转,举个例子,图2.7旋转30度(顺时针方向)后如图2.8所示: 可以看出,旋转后图象变大了.另一种做法是不让图象变大,转出的部分被裁剪掉.如图2.9所示. 我们采用第一种做法,首先给出变换矩阵.在我们熟悉的坐标系中,将一个点顺时针旋转a角后的坐标变换公式,如图2.10所示,r为该点到原点的距离,在旋转

图像编程学习笔记9——图像的锐化

锐化(sharpening)和平滑恰恰相反,它是通过增强高频分量来减少图象中的模糊,因此又称为高通滤波(high passfilter).锐化处理在增强图象边缘的同时增加了图象的噪声. 常用的锐化模板是拉普拉斯(Laplacian)模板(见(3.4)式),又是个数学家的名字,可见学好数学,走遍天下都不怕.   (3.4) 容易看出拉普拉斯模板的作法:先将自身与周围的8个象素相减,表示自身与周围象素的差别:再将这个差别加上自身作为新象素的灰度.可见,如果一片暗区出现了一个亮点,那么锐化处理的结果是

图像编程学习笔记6——图像转置

转置(transpose)是指将x,y坐标对换,图2.2的转置如图2.15所示. 图2.2 图2.15   图2.2的转置 要注意的是,转置和旋转900是有区别的,不信你可以试试:怎么旋转,图2.2也转不出图2.15来.另外,转置后图的宽高对换了.转置的变换矩阵很简单:                                                                                              (2.12) 镜象变换的源代码如下,因为和

图像编程学习笔记2——bmp位图平移

以下文字内容copy于<<数字图像处理编程入门>>,code为自己实现,是win32控制台程序. 2.1 平移 平移(translation)变换大概是几何变换中最简单的一种了. 如图2.1所示,初始坐标为(x0,y0)的点经过平移(tx,ty)(以向右,向下为正方向)后,坐标变为(x1,y1).这两点之间的关系是x1=x0+tx,y1=y0+ty.   图2.1    平移的示意图 以矩阵的形式表示为 (2.1)           我们更关心的是它的逆变换: (2.2) 这是因

图像编程学习笔记4——24位真彩色转换为灰度图像

以下文本内容来自http://zhidao.baidu.com/question/152910968.html中的部分内容 把RGB值转换为灰度值的公式:Gray   :=   Trunc(0.3   *   Red   +   0.59   *   Green   +   0.11   *   Blue);//这句用的是浮点运算在图像处理中,速度就是生命,能不用浮点运算,就最好不要用!Gray   :=   (30   *   Red   +   59   *   Green   +   11

信息-图像编程学习,位图存取

问题描述 图像编程学习,位图存取 请问 //图像数据信息是从左下角按行开始存储的 for(int i = 0; i < biHeight; i++ ) { for(int j = 0; j < biWidth; j++ ) { for(int k = 0; k < 3; k++ ) { int temp = *(pBmpBuf + i * lineByte + j + k); count++; outfile<<temp<<" "; if(co

Socket网络编程学习笔记(3):利用套接字助手类

在上一篇中已经介绍了利用Socket建立服务端和客户端进行通信,如果需要 的朋友可访问<Socket网络编程学习笔记(2):面向连接的Socket>.在本篇 中,将利用C#套接字的助手类来简化Socket编程,使得刚刚接触到网络编程的 朋友们更容易上手. 跟上篇一样,通过C#套接字的助手类来编程同样分 服务端和客户端. 一.服务端侦听模式 1.创建套接字与 IPEndPoint绑定,并设置为侦听模式. 1//创建IPEndPoint实例 2 IPEndPoint ipep = new IPEn