[置顶] 图像编程学习笔记5——图像镜像

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

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

[置顶] 图像编程学习笔记5——图像镜像_第1张图片

图2.13   图2.2的水平镜象

                                                                                 [置顶] 图像编程学习笔记5——图像镜像_第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;
}



你可能感兴趣的:(图像镜像,图像翻转,VC图像编程)