要求:
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;
}