图像增强基础——平滑和锐化

《数字图像处理》冈萨雷斯,图像增强基础——平滑与锐化,C语言实现

平滑(低通)空间滤波,测试像素为500*500

平滑代码如下:

void smooth(const char* filename)
{
	BITMAPFILEHEADER bmpFileHeader;
	BITMAPINFOHEADER bmpInfoHeader;
	RGBQUAD bmpColorTable[256];
	BYTE bmpValue[500 ][500];
	FILE* fp;
	if ((fp = fopen(filename, "rb")) == NULL)
	{
		printf("打开失败\n");
		exit(1);
	}
	//读取图像信息
	fread(&bmpFileHeader, sizeof(BITMAPFILEHEADER), 1, fp);
	fread(&bmpInfoHeader, sizeof(BITMAPINFOHEADER), 1, fp);
	fread(bmpColorTable, sizeof(RGBQUAD), 256, fp);
	fread(bmpValue, 1, 500 * 500, fp);
	//将图像灰度值存入二维数组中
	int grayValue_three[500][500] = {0};
	int grayValue_eleven[500][500] = { 0 };
	int grayValue_twentyone[500][500] = { 0 };
	for (int i = 0; i < 500; i++)
	{
		for (int j = 0; j < 500; j++)
		{
			grayValue_three[i][j] = bmpColorTable[bmpValue[i][j]].rgbBlue;
			grayValue_eleven[i][j] = bmpColorTable[bmpValue[i][j]].rgbBlue;
			grayValue_twentyone[i][j] = bmpColorTable[bmpValue[i][j]].rgbBlue;
		}
	}
	fclose(fp);
	//3*3,11*11,21*21盒式核对图像进行低通滤波
	int zero_fill_three[504][504] = { 0 };           // 零填充
	int zero_fill_eleven[520][520] = { 0 };          
	int zero_fill_twentyone[540][540] = { 0 };           
	for (int i = 2; i < 502; i++)        
	{
		for (int j = 2; j < 502; j++)
		{
			zero_fill_three[i][j] = grayValue_three[i-2][j-2];
		}
	}
	for (int i = 10; i < 510; i++)
	{
		for (int j = 10; j < 510; j++)
		{
			zero_fill_eleven[i][j] = grayValue_eleven[i - 10][j - 10];
		}
	}
	for (int i = 20; i < 520; i++)
	{
		for (int j = 20; j < 520; j++)
		{
			zero_fill_twentyone[i][j] = grayValue_twentyone[i - 20][j - 20];
		}
	}
    for (int i = 0; i < 500; i++)
	{
		for (int j = 0; j < 500; j++)
		{
			grayValue_three[i][j] =0;
			grayValue_eleven[i][j] = 0;
			grayValue_twentyone[i][j] = 0;
		}
	}

	for (int i = 2; i < 502; i++)               //进行卷积
	{
		for (int j = 2; j < 502; j++)
		{
			for (int a = 0; a < 3; a++)
			{
				for (int b = 0; b < 3; b++)
				{
					grayValue_three[i-2][j-2] +=(double)(zero_fill_three[i-a][j-b]);
				}
			}
			grayValue_three[i - 2][j - 2] = round(grayValue_three[i - 2][j - 2] / (3.0 * 3.0));
		}
	}
	for (int i = 10; i < 510; i++)               
	{
		for (int j = 10; j < 510; j++)
		{
			for (int a = 0; a < 11; a++)
			{
				for (int b = 0; b < 11; b++)
				{
					grayValue_eleven[i - 10][j - 10] += (double)(zero_fill_eleven[i - a][j - b]);
				}
			}
			grayValue_eleven[i - 10][j - 10] = round(grayValue_eleven[i - 10][j - 10] / (11.0 * 11.0));
		}
	}
	for (int i = 20; i < 520; i++)               
	{
		for (int j = 20; j < 520; j++)
		{
			for (int a = 0; a < 21; a++)
			{
				for (int b = 0; b < 21; b++)
				{
					grayValue_twentyone[i - 20][j - 20] += (double)(zero_fill_twentyone[i - a][j - b]);
				}
			}
			grayValue_twentyone[i - 20][j - 20] = round(grayValue_twentyone[i - 20][j - 20] / (21.0 * 21.0));
		}
	}
	//写入3*3盒式核进行低通滤波后的新图像
	fp = fopen("smooth_3.bmp", "wb");
	if (fp == NULL)
	{
		printf("写入失败\n");
		exit(1);
	}
	fwrite(&bmpFileHeader, sizeof(BITMAPFILEHEADER), 1, fp);
	fwrite(&bmpInfoHeader, sizeof(BITMAPINFOHEADER), 1, fp);
	fwrite(bmpColorTable, sizeof(RGBQUAD), 256, fp);
	for (int i = 0; i < 500 ; i++)
	{
		for (int j = 0; j < 500; j++)
		{
			fwrite(&grayValue_three[i][j], 1, 1, fp);
		}
	}
	fclose(fp);
	//写入11*11盒式核进行低通滤波后的新图像
	fp = fopen("smooth_11.bmp", "wb");
	if (fp == NULL)
	{
		printf("写入失败\n");
		exit(1);
	}
	fwrite(&bmpFileHeader, sizeof(BITMAPFILEHEADER), 1, fp);
	fwrite(&bmpInfoHeader, sizeof(BITMAPINFOHEADER), 1, fp);
	fwrite(bmpColorTable, sizeof(RGBQUAD), 256, fp);
	for (int i = 0; i < 500; i++)
	{
		for (int j = 0; j < 500; j++)
		{
			fwrite(&grayValue_eleven[i][j], 1, 1, fp);
		}
	}
	fclose(fp);
	//写入21*21盒式核进行低通滤波后的新图像
	fp = fopen("smooth_21.bmp", "wb");
	if (fp == NULL)
	{
		printf("写入失败\n");
		exit(1);
	}
	fwrite(&bmpFileHeader, sizeof(BITMAPFILEHEADER), 1, fp);
	fwrite(&bmpInfoHeader, sizeof(BITMAPINFOHEADER), 1, fp);
	fwrite(bmpColorTable, sizeof(RGBQUAD), 256, fp);
	for (int i = 0; i < 500; i++)
	{
		for (int j = 0; j < 500; j++)
		{
			fwrite(&grayValue_twentyone[i][j], 1, 1, fp);
		}
	}
	fclose(fp);

}

结果如下:

分别是原图,3*3盒式核滤波,11*11盒式核滤波,21*21盒式核滤波的结果

图像增强基础——平滑和锐化_第1张图片 图像增强基础——平滑和锐化_第2张图片

 图像增强基础——平滑和锐化_第3张图片图像增强基础——平滑和锐化_第4张图片

锐化(高通)滤波器,其实就是核的系数不同而已,原理和平滑挺类似的。

拉普拉斯算子:

void laplace_sharpen(const char* filename)
{
	BITMAPFILEHEADER bmpFileHeader;
	BITMAPINFOHEADER bmpInfoHeader;
	RGBQUAD bmpColorTable[256];
	BYTE bmpValue[540][468];
	FILE* fp;
	if ((fp = fopen(filename, "rb")) == NULL)
	{
		printf("打开失败\n");
		exit(1);
	}
	//读取图像信息
	fread(&bmpFileHeader, sizeof(BITMAPFILEHEADER), 1, fp);
	fread(&bmpInfoHeader, sizeof(BITMAPINFOHEADER), 1, fp);
	fread(bmpColorTable, sizeof(RGBQUAD), 256, fp);
	fread(bmpValue, 1, 540 * 468, fp);
	//将图像灰度值存入二维数组中,g(x,y)=f(x,y)-[▽^2 f(x,y)]
	int grayValue1[540][468] = { 0 };
	for (int i = 0; i < 540; i++)
	{
		for (int j = 0; j < 468; j++)
		{
			grayValue1[i][j] = bmpColorTable[bmpValue[i][j]].rgbBlue;
		}
	}
	fclose(fp);
	int zero_fill[544][472] = { 0 };           // 零填充
	for (int i = 2; i < 542; i++)
	{
		for (int j = 2; j < 470; j++)
		{
			zero_fill[i][j] = grayValue1[i - 2][j - 2];
		}
	}
	for (int i = 2; i < 542; i++)               //进行卷积
	{
		for (int j = 2; j < 470; j++)
		{
			grayValue1[i - 2][j - 2] = zero_fill[i - 1][j] + zero_fill[i - 1][j - 2] + zero_fill[i - 2][j - 1] + zero_fill[i][j - 1] - 4* zero_fill[i - 1][j - 1];
			if (grayValue1[i-2][j-2] < 0)
			{
				grayValue1[i-2][j-2] = 0;
			}
		}
	}
	
	//写入laplace算子进行高通滤波后的新图像
	fp = fopen("laplace_sharpen.bmp", "wb");
	if (fp == NULL)
	{
		printf("写入失败\n");
		exit(1);
	}
	fwrite(&bmpFileHeader, sizeof(BITMAPFILEHEADER), 1, fp);
	fwrite(&bmpInfoHeader, sizeof(BITMAPINFOHEADER), 1, fp);
	fwrite(bmpColorTable, sizeof(RGBQUAD), 256, fp);
	for (int i = 0; i < 540; i++)
	{
		for (int j = 0; j < 468; j++)
		{
			fwrite(&grayValue1[i][j], 1, 1, fp);
		}
	}
	fclose(fp);
}

结果如图:

图像增强基础——平滑和锐化_第5张图片图像增强基础——平滑和锐化_第6张图片

 梯度算子:我这里用到的是Sobel算子,很奇怪,用matlab就和书上的图一样,用C语言写,左边和下面会出现白色边边。然后我加了个阈值,效果会好一点。

void sobel_sharpen(const char* filename)
{
	BITMAPFILEHEADER bmpFileHeader;
	BITMAPINFOHEADER bmpInfoHeader;
	RGBQUAD bmpColorTable[256];
	BYTE bmpValue[932][940];
	FILE* fp;
	if ((fp = fopen(filename, "rb")) == NULL)
	{
		printf("打开失败\n");
		exit(1);
	}
	//读取图像信息
	fread(&bmpFileHeader, sizeof(BITMAPFILEHEADER), 1, fp);
	fread(&bmpInfoHeader, sizeof(BITMAPINFOHEADER), 1, fp);
	fread(bmpColorTable, sizeof(RGBQUAD), 256, fp);
	fread(bmpValue, 1, 940 *932, fp);
	//将图像灰度值存入二维数组中
	int grayValue[932][940] = { 0 };
	for (int i = 0; i < 932; i++)
	{
		for (int j = 0; j < 940; j++)
		{
			grayValue[i][j] = bmpColorTable[bmpValue[i][j]].rgbBlue;
		}
	}
	fclose(fp);
	int sum, avg;
	sum = 0;
	for (int i = 0; i < 932; i++)
	{
		for (int j = 0; j < 940; j++)
		{
			sum += grayValue[i][j];
		}
	}
	avg = sum / (940 * 932);
	int zero_fill[936][944] = { 0 };           // 零填充
	for (int i = 2; i < 934; i++)
	{
		for (int j = 2; j < 942; j++)
		{
			zero_fill[i][j] = grayValue[i - 2][j - 2];
		}
	}
	int grayValue_x[932][940] = { 0 };
	int grayValue_y[932][940] = { 0 };
	for (int i = 2; i < 934; i++)               //进行卷积
	{
		for (int j = 2; j < 942; j++)
		{
			grayValue_y[i - 2][j - 2] = zero_fill[i][j] + 2 * zero_fill[i - 1][j] + zero_fill[i - 2][j] - zero_fill[i - 2][j - 2] - zero_fill[i][j - 2] - 2 * zero_fill[i - 1][j - 2];
			grayValue_x[i - 2][j - 2] = zero_fill[i][j] + 2 * zero_fill[i][j - 1] + zero_fill[i][j - 2] - zero_fill[i - 2][j - 2] - zero_fill[i - 2][j] - 2 * zero_fill[i - 2][j - 1];
			if (grayValue_y[i - 2][j - 2] > avg || grayValue_x[i - 2][j - 2] > avg)    //阈值
			{
				grayValue_y[i - 2][j - 2] = 0;
				grayValue_x[i - 2][j - 2] = 0;
			}
		}
	}
	for (int i = 0; i < 932; i++)
	{
		for (int j = 0; j < 940; j++)
		{
			grayValue[i][j] = sqrt(grayValue_x[i][j] * grayValue_x[i][j]+ grayValue_y[i][j] * grayValue_y[i][j]);
		}
	}
	//写入sobel算子进行高通滤波后的新图像
	fp = fopen("sobel_sharpen.bmp", "wb");
	if (fp == NULL)
	{
		printf("写入失败\n");
		exit(1);
	}
	fwrite(&bmpFileHeader, sizeof(BITMAPFILEHEADER), 1, fp);
	fwrite(&bmpInfoHeader, sizeof(BITMAPINFOHEADER), 1, fp);
	fwrite(bmpColorTable, sizeof(RGBQUAD), 256, fp);
	for (int i = 0; i < 932; i++)
	{
		for (int j = 0; j < 940; j++)
		{
			fwrite(&grayValue[i][j], 1, 1, fp);
		}
	}
	fclose(fp);
}

结果如图:

图像增强基础——平滑和锐化_第7张图片

你可能感兴趣的:(数字图像处理(冈萨雷斯),c语言,图像处理)