以下文字内容copy于<<数字图像处理编程入门>>,code为自己实现,是win32控制台程序。
镜象(mirror)分水平镜象和垂直镜象两种。图2.2的水平镜象和垂直镜象分别如图2.13和图2.14所示
图2.13 图2.2的水平镜象
图2.14 图2.2的垂直镜象
镜象的变换矩阵很简单。设原图宽为w,高为h,变换后,图的宽和高不变。
水平镜象的变化矩阵为:
(2.10)
垂直镜象的变化矩阵为:
(2.11)
镜象变换的源代码如下,因为和平移的那段程序很类似,程序中的注释就简单一些。
- /**
- * 程序名: Mirror.cpp
- * 功 能: 实现灰度图像的水平镜像和垂直镜像
- * 测试图片test.bmp放在工程目录下
- */
- #include <iostream>
- #include <windows.h>
- #include <fstream>
- #include <cstring>
- using namespace std;
- BITMAPFILEHEADER bmpFileHeader; //bmp文件头
- BITMAPINFOHEADER bmpInfoHeader; //bmp信息头
- RGBQUAD *pColorTable; //bmp颜色表
- unsigned char *pBmpData; //bmp位图数据
- unsigned char *pXBmpData; //水平镜像bmp位图数据
- unsigned char *pYBmpData; //垂直镜像bmp位图数据
- /**
- * 函数名: readBmp
- * 参 数: fileName -- 指向文件名的指针
- * 功 能: 读取将要处理的图片的信息,成功返回TRUE
- */
- bool readBmp(char *fileName)
- {
- FILE *fp = fopen(fileName,"rb"); //以二进制读方式打开
- if (NULL == fp)
- {
- cout<<"open failure!"<<endl;
- return FALSE;
- }
- //获得图片数据
- fread(&bmpFileHeader,sizeof(BITMAPFILEHEADER),1,fp);
- fread(&bmpInfoHeader,sizeof(BITMAPINFOHEADER),1,fp);
- pColorTable = new RGBQUAD[256];
- fread(pColorTable,sizeof(RGBQUAD),256,fp);
- int imgSize = bmpInfoHeader.biSizeImage;
- pBmpData = new unsigned char[imgSize];
- //因为大小没有改变,所以一起处理了
- pXBmpData = new unsigned char[imgSize];
- pYBmpData = new unsigned char[imgSize];
- fread(pBmpData,sizeof(unsigned char),imgSize,fp);
- fclose(fp); //关闭文件
- return TRUE;
- }
- /**
- * 函数名: mirror
- * 功 能: 对图片进行水平和垂直镜像操作
- */
- void mirror()
- {
- int height = bmpInfoHeader.biHeight;
- int width = bmpInfoHeader.biWidth;
- int imgSize = bmpInfoHeader.biSizeImage;
- memset(pXBmpData,0,sizeof(unsigned char )*imgSize);
- memset(pYBmpData,0,sizeof(unsigned char )*imgSize);
- int lineByte = (width * 8 + 31) / 32 * 4; //每行像素的字节数
- for(int i = 0; i < height; i++ )
- {
- for(int j = 0; j < width; j++ )
- {
- *(pXBmpData + i*lineByte + width - 1 - j) = *(pBmpData + i*lineByte + j); //水平镜像
- *(pYBmpData + (height - i - 1)*lineByte + j) = *(pBmpData + i*lineByte + j); //垂直镜像
- }
- }
- }
- /**
- * 函数名: writeBmp
- * 参 数: fileName -- 处理完之后的bmp图像
- * 功 能: 写入文件数据到相应的文件中
- */
- bool writeBmp(char *fileName,unsigned char *bmpData)
- {
- FILE *fp = fopen(fileName,"wb"); //以二进制写方式打开
- if (NULL == fp)
- {
- cout<<"open failure!"<<endl;
- return FALSE;
- }
- int imgSize = bmpInfoHeader.biSizeImage;
- //写入数据
- fwrite(&bmpFileHeader,sizeof(BITMAPFILEHEADER),1,fp);
- fwrite(&bmpInfoHeader,sizeof(BITMAPINFOHEADER),1,fp);
- fwrite(pColorTable,sizeof(RGBQUAD),256,fp);
- fwrite(bmpData,sizeof(unsigned char),imgSize,fp);
- fclose(fp); //关闭文件
- return TRUE;
- }
- /**
- * 函数名: work
- * 功 能: 主要处理
- */
- void work()
- {
- char readFileName[] = "test.bmp";
- if (!readBmp(readFileName))
- {
- cout<<"read failure!"<<endl;
- return ;
- }
- mirror();
- char writeFileNameX[] = "X.bmp";
- char writeFileNameY[] = "Y.bmp";
- if (!writeBmp(writeFileNameX,pXBmpData))
- {
- cout<<"X write failure!"<<endl;
- return ;
- }
- if (!writeBmp(writeFileNameY,pYBmpData))
- {
- cout<<"Y write failure!"<<endl;
- return ;
- }
- //释放
- delete []pColorTable;
- delete []pBmpData;
- delete []pXBmpData;
- delete []pYBmpData;
- cout<<"mirror success!"<<endl;
- }
- int main()
- {
- work();
- return 0;
- }