考虑如下的增强算法:在每个像素位置,计算其水平方向上左边一个和右边一个位置的两个像素的灰度差H,计算其垂直方向上高一个和低一个位置的两个像素的灰度差V。如果V>H,则将该像素的灰度变为水平方向上两个像素的灰度和的平均值;否则,将该像素的灰度变为垂直方向上的两个像素的灰度和的平均值。
(1)讨论该算法的效果特点。
(2)如果反复利用该算法,可获得什么效果?
实验代码
#include <iostream>
#include <cstdio>
#include <fstream>
using namespace std;
void changeyuv(unsigned char* file, unsigned char* fileNew, int height, int width);
int Mask(unsigned char* ini, int i, int j, int height, int width);
int main()
{
int lenawidth = 512;
int lenaheight = 512;
int moonwidth = 464;
int moonheight = 538;
int starskywidth = 485;
int starskyheight = 528;
int lenasize = lenaheight * lenawidth * 3;
int moonsize = moonheight * moonwidth * 3;
int starsize = starskyheight * starskywidth * 3;
int downwidth = 256;
int downheight = 256;
int downsize = downheight * downwidth * 3;
//读入三个文件,读出三个文件
ifstream downfile("down.rgb", ios::binary);
ifstream lenafile("lena_noise.yuv", ios::binary);
ifstream starskyfile("starsky.yuv", ios::binary);
ifstream moonfile("moon.yuv", ios::binary);
if (!downfile) { cout << "error to open down!" << endl; }
if (!lenafile) { cout << "error to open lena!" << endl; }
if (!starskyfile) { cout << "error to open starsky!" << endl; }
if (!moonfile) { cout << "error to open moon!" << endl; }
ofstream downNewFile("down_new.rgb", ios::binary);
ofstream lenaNewFile("lena_new.yuv", ios::binary);
ofstream starskyNewFile("starsky_new.yuv", ios::binary);
ofstream moonLaNewFile("moon_Laplace_new.yuv", ios::binary);
if (!downNewFile) { cout << "error to create down!" << endl; }
if (!lenaNewFile) { cout << "error to create lena!" << endl; }
if (!starskyNewFile) { cout << "error to create starsky!" << endl; }
if (!moonLaNewFile) { cout << "error to create moonfile1!" << endl; }
unsigned char* down = new unsigned char[downsize];
unsigned char* lena = new unsigned char[lenasize];
unsigned char* starsky = new unsigned char[starsize];
unsigned char* moon = new unsigned char[moonsize];
unsigned char* downNew = new unsigned char[downsize];
unsigned char* lenaNew = new unsigned char[lenasize];
unsigned char* starskyNew = new unsigned char[starsize];
unsigned char* moonLaNew = new unsigned char[moonsize];
downfile.read((char*)down, downsize);
lenafile.read((char*)lena, lenasize);
starskyfile.read((char*)starsky, starsize);
moonfile.read((char*)moon, moonsize);
for (int i = 0; i < 256; i++)
{
if (i % 2 == 0)
{
changeyuv(down, downNew, downheight * 3, downwidth);
changeyuv(lena, lenaNew, lenaheight * 3, lenawidth);
changeyuv(moon, moonLaNew, moonheight * 3, moonwidth);
changeyuv(starsky, starskyNew, starskyheight * 3, starskywidth);
}
else
{
changeyuv(downNew, down, downheight * 3, downwidth);
changeyuv(lenaNew, lena, lenaheight * 3, lenawidth);
changeyuv(moonLaNew, moon, moonheight * 3, moonwidth);
changeyuv(starskyNew, starsky, starskyheight * 3, starskywidth);
}
}
/*changeyuv(down, downNew, downheight*3, downwidth);
changeyuv(lena, lenaNew, lenaheight*3, lenawidth);
changeyuv(moon, moonLaNew, moonheight*3, moonwidth);
changeyuv(starsky, starskyNew, starskyheight*3, starskywidth);*/
downNewFile.write((char*)downNew, downsize);
lenaNewFile.write((char*)lenaNew, lenasize);
starskyNewFile.write((char*)starskyNew, starsize);
moonLaNewFile.write((char*)moonLaNew, moonsize);
//删除指针
if (lena) { delete[]lena; lena = NULL; }
if (starsky) { delete[]starsky; starsky = NULL; }
if (moon) { delete[]moon; moon = NULL; }
if (lenaNew) { delete[]lenaNew; lenaNew = NULL; }
if (starskyNew) { delete[]starskyNew; starskyNew = NULL; }
if (moonLaNew) { delete[]moonLaNew; moonLaNew = NULL; }
//关闭打开的文件
lenafile.close();
starskyfile.close();
moonfile.close();
lenaNewFile.close();
starskyNewFile.close();
moonLaNewFile.close();
return 0;
}
void changeyuv(unsigned char* file, unsigned char* fileNew, int height, int width)
{
for (int i = 0; i < height; i++)
{
for (int j = 0; j < width; j++)
{
fileNew[i * width + j] = Mask(file, i, j, height, width)/2;
}
}
}
int Mask(unsigned char* ini, int i, int j, int height, int width)
{
int del_x = 0;
int del_y = 0;
int sum_x = 0;
int sum_y = 0;
int ans;
if (i == 0)
{
del_x = abs(ini[(i + 1) * width + j]);
sum_x = abs(ini[(i + 1) * width + j]);
}
else if (i == height)
{
del_x = abs(ini[(i - 1) * width + j]);
sum_x = abs(ini[(i - 1) * width + j]);
}
else
{
del_x = abs(ini[(i + 1) * width + j] - ini[(i - 1) * width + j]);
sum_x = abs(ini[(i + 1) * width + j] + ini[(i - 1) * width + j]);
}
if (j == 0)
{
del_y = abs(ini[i * width + j + 1]);
sum_y = abs(ini[i * width + j + 1]);
}
else if (j == width)
{
del_y = abs(ini[i * width + j - 1]);
sum_y = abs(ini[i * width + j - 1]);
}
else
{
del_y = abs(ini[i * width + j + 1] - ini[i * width + j - 1]);
sum_y = abs(ini[i * width + j + 1] + ini[i * width + j - 1]);
}
if (del_x > del_y)
return sum_y;
else
return sum_x;
}
实验结果
运行1次
RGB文件三个通道独立,并没有进行捆绑计算。
运行256次
实验结论
(1)效果:和平滑滤波具有相同的效果。
(2)结果:图像逐渐模糊,但是噪声干扰变得不太明显,整个图像趋于平滑,整幅图像的像素点逐步趋于同一点。