图像信息处理实验五

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_32146369/article/details/78564869

要求:

1.Image mean filtering

2.Laplacian image enhancement

#include <stdio.h>
#include <Windows.h>

//线性均值滤波
void imf(char* a, char* b)
{
	BITMAPFILEHEADER fileHeader;// 位图头文件
	BITMAPINFOHEADER infoHeader;// 位图信息头
	FILE* pFile = fopen(a, "rb");
	if (pFile == NULL)
	{
		printf("打开文件失败\n");
		exit(-1);
	}
	// 读取头信息
	fread(&fileHeader, sizeof(BITMAPFILEHEADER), 1, pFile);   //读取文件头
	fread(&infoHeader, sizeof(BITMAPINFOHEADER), 1, pFile);   //读取信息头
	WORD bitCount = infoHeader.biBitCount;//色彩的位数
	if (bitCount == 16)
	{
		exit(-1);
	}
	int Clr = 0;

	RGBQUAD *QUAD = NULL;
	if (bitCount < 16)
	{

		Clr = infoHeader.biClrUsed ? infoHeader.biClrUsed : 1 << bitCount;
		if (Clr>256)
			Clr = 0;
	}
	// 读取调色板
	int i = 0, j = 0;
	if (Clr > 0)
	{
		QUAD = (RGBQUAD*)malloc(sizeof(RGBQUAD)*Clr);
		fread(QUAD, sizeof(RGBQUAD)*Clr, 1, pFile);
		for (i = 0; i < Clr; i++)
		{
			QUAD[i].rgbRed = QUAD[i].rgbBlue = QUAD[i].rgbGreen =
				(BYTE)(0.3 * QUAD[i].rgbRed + 0.59 * QUAD[i].rgbGreen + 0.11 * QUAD[i].rgbBlue);  //灰度图像三个都是y
		}
	}
	LONG pW = infoHeader.biWidth;     //图像数据的宽度
	LONG pH = infoHeader.biHeight;    //图像数据的高度

	int pSize = ((pW * bitCount)>>3)*pH;  //图像数据大小
	BYTE* P = (BYTE*)malloc(pSize);   //申请空间保存图像数据
	int LineSize = ((pW * bitCount)>> 3);  //行数据大小
	fread(P, pSize, 1, pFile);     //存入图像数据
	//先转grey图像
	if (Clr == 0)
	{
		for (i = 0; i < pH; i++)//行
		{
			if (bitCount == 24)
			{
				for (j = 0; j < pW*3; j = j + 3)// 列
				{
					int n = i*LineSize + j;
					P[n] = P[n + 1] = P[n + 2] = (BYTE)(0.299*P[n] + 0.587*P[n + 1] + 0.114*P[n + 2]); //分别是r,g,b分量

				}
			}

		}
	}

    //均值滤波
        for (i = 1; i < pH - 1; i++)//行
		{
			for (j = 3; j < (pW - 1) * 3; j = j + 3)// 列
			{
				//int n = i*LineSize + j;
				P[i*LineSize + j] = P[i*LineSize + j + 1] = P[i*LineSize + j + 2] = (BYTE)((P[i*LineSize+j]+P[i*LineSize+j+3]+P[i*LineSize+j-3]+P[(i-1)*LineSize+j]+P[(i-1)*LineSize+j+3]+P[(i-1)*LineSize+j-3]+P[(i+1)*LineSize+j-3]+P[(i+1)*LineSize+j+3]+P[(i+1)*LineSize+j])/9);  //等于9个像素点的均值

			}
		}
	FILE* dFile = fopen(b, "wb");//创建目标文件

	fwrite(&fileHeader, sizeof(BITMAPFILEHEADER), 1, dFile);   //写入文件头

	fwrite(&infoHeader, sizeof(BITMAPINFOHEADER), 1, dFile);  //写入文件信息头
	if (QUAD)
	{
		fwrite(QUAD, sizeof(RGBQUAD)* Clr, 1, dFile);
	}
	//写入图像数据
	fwrite(P, pSize, 1, dFile);
	fclose(dFile);

	if (QUAD)
	{
		free(QUAD);
		QUAD = NULL;
	}
	if (P)
	{
		free(P);
		P = NULL;
	}
}

void lie(char* a, char* b)
{
	BITMAPFILEHEADER fileHeader;// 位图头文件
	BITMAPINFOHEADER infoHeader;// 位图信息头
	FILE* pFile = fopen(a, "rb");
	if (pFile == NULL)
	{
		printf("打开文件失败\n");
		exit(-1);
	}
	// 读取头信息
	fread(&fileHeader, sizeof(BITMAPFILEHEADER), 1, pFile);   //读取文件头
	fread(&infoHeader, sizeof(BITMAPINFOHEADER), 1, pFile);   //读取信息头
	WORD bitCount = infoHeader.biBitCount;//色彩的位数
	if (bitCount == 16)
	{
		exit(-1);
	}
	int Clr = 0;

	RGBQUAD *QUAD = NULL;
	if (bitCount < 16)
	{

		Clr = infoHeader.biClrUsed ? infoHeader.biClrUsed : 1 << bitCount;
		if (Clr>256)
			Clr = 0;
	}
	// 读取调色板
	int i = 0, j = 0;
	if (Clr > 0)
	{
		QUAD = (RGBQUAD*)malloc(sizeof(RGBQUAD)*Clr);
		fread(QUAD, sizeof(RGBQUAD)*Clr, 1, pFile);
		for (i = 0; i < Clr; i++)
		{
			QUAD[i].rgbRed = QUAD[i].rgbBlue = QUAD[i].rgbGreen =
				(BYTE)(0.3 * QUAD[i].rgbRed + 0.59 * QUAD[i].rgbGreen + 0.11 * QUAD[i].rgbBlue);  //灰度图像三个都是y
		}
	}
	LONG pW = infoHeader.biWidth;     //图像数据的宽度
	LONG pH = infoHeader.biHeight;    //图像数据的高度

	int pSize = ((pW * bitCount)>>3)*pH;  //图像数据大小
	BYTE* P = (BYTE*)malloc(pSize);   //申请空间保存图像数据
	int LineSize = ((pW * bitCount)>> 3);  //行数据大小
	fread(P, pSize, 1, pFile);     //存入图像数据
	//先转grey图像
	if (Clr == 0)
	{
		for (i = 0; i < pH; i++)//行
		{
			if (bitCount == 24)
			{
				for (j = 0; j < pW*3; j = j + 3)// 列
				{
					int n = i*LineSize + j;
					P[n] = P[n + 1] = P[n + 2] = (BYTE)(0.299*P[n] + 0.587*P[n + 1] + 0.114*P[n + 2]); //分别是r,g,b分量

				}
			}

		}
	}
    //拉普拉斯
    int w; //和
        for (i = 1; i < pH - 1; i++)//行
		{
			for (j = 3; j < (pW - 1) * 3; j = j + 3)// 列
			{
				//int n = i*LineSize + j;
				w=P[i*LineSize+j+3]+P[i*LineSize+j-3]+P[(i-1)*LineSize+j]+P[(i-1)*LineSize+j+3]+P[(i-1)*LineSize+j-3]+P[(i+1)*LineSize+j-3]+P[(i+1)*LineSize+j+3]+P[(i+1)*LineSize+j]-P[i*LineSize+j]*8;
				w*=0.1;
				//权重正负分类

				if(w>=0){
                    //
                    if(P[i*LineSize+j]+w>255)
                        P[i*LineSize+j]=P[i*LineSize+j+1]=P[i*LineSize+j+2]=(BYTE)(255);
                    else if(P[i*LineSize+j]+w<0)
                        P[i*LineSize+j]=P[i*LineSize+j+1]=P[i*LineSize+j+2]=(BYTE)(0);
                    else
                        P[i*LineSize+j]=P[i*LineSize+j+1]=P[i*LineSize+j+2]=(BYTE)(P[i*LineSize+j]+w);
				}

                else{
                    if(P[i*LineSize+j]-w>255)
                        P[i*LineSize+j]=P[i*LineSize+j+1]=P[i*LineSize+j+2]=(BYTE)(255);
                    else if(P[i*LineSize+j]-w<0)
                        P[i*LineSize+j]=P[i*LineSize+j+1]=P[i*LineSize+j+2]=(BYTE)(0);
                    else
                        P[i*LineSize+j]=P[i*LineSize+j+1]=P[i*LineSize+j+2]=(BYTE)(P[i*LineSize+j]-w);
                }
			}
		}
	FILE* dFile = fopen(b, "wb");//创建目标文件

	fwrite(&fileHeader, sizeof(BITMAPFILEHEADER), 1, dFile);   //写入文件头

	fwrite(&infoHeader, sizeof(BITMAPINFOHEADER), 1, dFile);  //写入文件信息头
	if (QUAD)
	{
		fwrite(QUAD, sizeof(RGBQUAD)* Clr, 1, dFile);
	}
	//写入图像数据
	fwrite(P, pSize, 1, dFile);
	fclose(dFile);

	if (QUAD)
	{
		free(QUAD);
		QUAD = NULL;
	}
	if (P)
	{
		free(P);
		P = NULL;
	}
}
int main()
{
	imf("a.bmp", "imfa.bmp");
    lie("a.bmp", "liea.bmp");

	return 0;
}


猜你喜欢

转载自blog.csdn.net/qq_32146369/article/details/78564869