數字視頻處理(四)——作業中出現的一個奇怪的增強算法

考慮如下的增強算法:在每個像素位置,計算其水平方向上左邊一個和右邊一個位置的兩個像素的灰度差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)結果:圖像逐漸模糊,但是噪聲干擾變得不太明顯,整個圖像趨於平滑,整幅圖像的像素點逐步趨於同一點。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章