以下文字内容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;
- }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!