Ga teng bo’lganda


Download 26.55 Kb.
Sana28.12.2022
Hajmi26.55 Kb.
#1071175
Bog'liq
Tasvirlar


Tasvirlarni Adamar qayta ishlash bazisi bilan qayta ishlaganda ularni hajmini kamaytirishga harakat qilish kerak. Hozirgi paytda asosiy vazifa real vaqt davomida qabul qilinayotgan malumotlarni hajmini kamaytirgan holda kampyuter xotirasida saqlash talab etiladi. Bundan asosiy maqsad xotira muammosini oldini olishdir.
Buni dasturiy qismida avvallo Adamar qayta o’zgartirishning matritsasini topishimiz kerak. Adamar matritsasi asosan +1 va -1 dan tashkil topadi. +1 bu bor degani va -1 esa usha yacheyka bushligini anglatadi. Unung ko’rinishi quyidagicha aks etadi:

Rasm1. N=4 ga teng bo’lganda.

Рис. 2. Базисные изображения 8x8 для преобразования Уолша-Адамара и программа Matlab
Ядра WHT изображены в графической форме на рис. 3.42 при N = 4, где белый цвет означает +1, а черный —1 (для наглядности множитель 1/N опущен). Строки и столбцы в блоках занумерованы значениями и и v от 0 до 3, соответственно. Число смен знаков в строке или в столбце матрицы называется частотностью строки или столбца. Строки и столбцы на этом рисунке упорядочены по возрастанию частотности. Некоторые авторы предпочитают изображать ядра неупорядоченно, так, как это было определено Уол-шем и Адамаром .
Kerakli o’lchamdagi Adamar matritsasi quyidagi dasturiy kodda keltirilgan:
public int[,] Calc_H(int size)
{
int[,] H = new int[size, size];
H[0, 0] = 1;

Parallel.For(0, size, i =>


{
for (int j = 0; j < size; j++)
{
H[i, j] = -1;
}
});

for (int n = 1; n < size; n += n)


{
Parallel.For(0, n, i =>
{
for (int j = 0; j < n; j++)
{
H[i + n, j] = H[i, j];
H[i, j + n] = H[i, j];
H[i + n, j + n] = (-1) * H[i, j];
}
});
}
return H;
}

Yuqoridagi kodda birinchi bo’lib kerakli ikki o’lchamdagi matritsa olinadi. Bunda matritsa o’lchami biz talab qilgan ko’rinishda ham bo’lishi mumkin, bu kodda tasvir o’lchamiga qarab matritsa o’lchami olingan. Ya’ni tasvir o’lchamini size o’zgaruvchisi bilan belgiladik. Tasvir dasturga yuklanganda avtamatik holda size o’zgaruvchisi o’ziga tasvir eni va bo’yini qiymatlarini o’zlashtirib oladi.


Dasturda kerakli ikki o’lchamli tasvirni chaqirib olish kerakli tugmani bosish orqali amalga oshiriladi. Bunda quyidagicha kod yoziladi:
private void button_Open_Click(object sender, EventArgs e)
{
try
{
OpenFileDialog open = new OpenFileDialog();
open.Filter = "Image Files(*.jpg; *.jpeg; *.gif; *.bmp)|*.jpg; *.jpeg; *.gif; *.bmp";
if (open.ShowDialog() == DialogResult.OK)
{
Bitmap bit = new Bitmap(open.FileName);
pictureBox_Original.Image = bit;
}
H = Calc_H(pictureBox_Original.Width);
button_Red.Enabled = true;
button_Green.Enabled = true;
button_Blue.Enabled = true;
button_Adamar.Enabled = true;
}
catch (Exception)
{
throw new ApplicationException("Failed loading image");
}
}
Kerakli tasvir yuklab olingach uni qayta ishlash tugmasini bosish orqali keying etapga o’tiladi. Qayta ishlash quyidagi tartibda amalga oshadi. Bunda tasvir RGB ranglarni alohida matritsalarga ajratib, Adamar matritsasiga ko’paytirib chiqiladi. Dasturiy kodi quyidagicha aks etadi:
public double[,] Multiply_matrix(double[,] x, int[,] y)
{
double[,] res = new double[256, 256];
double temp = 0;
for (int i = 0; i < 256; i++)
{
for (int j = 0; j < 256; j++)
{
temp = 0;
for (int k = 0; k < 256; k++)
{
temp = temp + x[k, j] * y[i, k];
}
res[i, j] = temp;
}
}
return res;
}
Tasvirning har bir rang kanalini Adamar matritsasiga ko’paytirib yig’indini olganimizda bazi hollarda {0,255} oraliqqa mos tushmasligi mumkin. Buning oldini olish uchun biz shart kiritamiz va bu shartni alohida funksiya sifatida yozamiz:
public int dec(double son)
{
int IntValue = (int)Math.Round(son, 0);
if (Math.Abs(IntValue) > 255)
return 255;
if (IntValue < 0)
return Math.Abs(IntValue);
return (int)IntValue;
}
Keying bosqichda qiladigan ishimiz shundan iboratki, Adamar qayta ishlash formulasidan kelib chiqqan holda tasvirning har bir rang kanalining har bir qiymatini Adamar matritsasi o’lchamiga bo’lib chiqiladi:
public double[,] MatrixDivideTo256(double[,] x)
{
double[,] res = new double[256, 256];
for (int i = 0; i < 256; i++)
{
for (int j = 0; j < 256; j++)
{
res[i, j] = x[i, j] / 256;
}
}
return res;
}
Oxirgi etaplardan biri bu qayta o’zgartirish hosil qilingan tasvir matritsasini dastur oynasiga chiqarishdan iborat.
private void button_decode_Click(object sender, EventArgs e)
{
img = new Bitmap(pictureBox_Original.Image);
double[,] tmpR1 = new double[img.Width, img.Height];
double[,] tmpG1 = new double[img.Width, img.Height];
double[,] tmpB1 = new double[img.Width, img.Height];

Stopwatch stopWatch = new Stopwatch();


stopWatch.Start();
Parallel.For(0, img.Width, i =>
{
for (int y = 0; y < img.Height; y++)
{
Color p = img.GetPixel(x, y);
tmpR1[x, y] = p.R;
tmpG1[x, y] = p.G;
tmpB1[x, y] = p.B;
}
});
double[,] tmpR2 = Multiply_matrix(MatrixDivideTo256(RedAdamar), H);
double[,] tmpG2 = Multiply_matrix(MatrixDivideTo256(GreenAdamar), H);
double[,] tmpB2 = Multiply_matrix(MatrixDivideTo256(BlueAdamar), H);
img = new Bitmap(pictureBox_Original.Width, pictureBox_Original.Height);

Parallel.For(0, img.Width, x =>


{
for (int y = 0; y < img.Height; y++)
{
c = Color.FromArgb(dec(tmpR2[x, y]), dec(tmpG2[x, y]), dec(tmpB2[x, y]));
img.SetPixel(x, y, c);
}
});
pictureBox_Changed.Image = img;
stopWatch.Stop();
TimeSpan ts1 = stopWatch.Elapsed;
stopWatch = new Stopwatch();
stopWatch.Start();

img = new Bitmap(pictureBox_Original.Image);


for (int x = 0; x < img.Width; x++)
{
for (int y = 0; y < img.Height; y++)
{
Color p = img.GetPixel(x, y);
tmpR1[x, y] = p.R;
tmpG1[x, y] = p.G;
tmpB1[x, y] = p.B;
}
}
tmpR2 = Multiply_matrix(MatrixDivideTo256(RedAdamar), H);
tmpG2 = Multiply_matrix(MatrixDivideTo256(GreenAdamar), H);
tmpB2 = Multiply_matrix(MatrixDivideTo256(BlueAdamar), H);
img = new Bitmap(pictureBox_Original.Width, pictureBox_Original.Height);
for (int x = 0; x < img.Width; x++)
{
for (int y = 0; y < img.Height; y++)
{
c = Color.FromArgb(dec(tmpR2[x, y]), dec(tmpG2[x, y]), dec(tmpB2[x, y]));
img.SetPixel(x, y, c);
}
}
stopWatch.Stop();
TimeSpan ts2 = stopWatch.Elapsed;

string mess1 = "1 - Vaqt: " + String.Format("{0:00}:{1:00}:{2:00}.{3:00}", ts1.Hours, ts1.Minutes, ts1.Seconds, ts1.Milliseconds) + "\n";


string mess2 = "2 - Vaqt: " + String.Format("{0:00}:{1:00}:{2:00}.{3:00}", ts2.Hours, ts2.Minutes, ts2.Seconds, ts2.Milliseconds) + "\n";
richTextBox2.Text = "Qayta ishlash:\n" + mess1 + mess2;

TimeSpan ts = ts1 - ts2;


string mess = "Unumdorlik: " + String.Format("{0:00}:{1:00}:{2:00}.{3:00}", ts.Hours, ts.Minutes, ts.Seconds, ts.Milliseconds) + "\n";
richTextBox2.Text += mess;
}
Shu tariqa qayta ishlanayotgan tasvir spektiri olinadi. Va bu spektr orqali tasvirni qayta tiklash ham shu tariqa bosqichma-bosqich amalga oshiriladi.
Natijada biz tasvirlarni Adamar qayta o’zgartirishi bilan qayta ishlaganimizda parallelashtirish algoritmi bilan amal oshirganimizda 1.2-1.4 marotoba unumdorlikka erishamiz va tasvir hajmini 14% gacha kamaytirihsimiz mumkin ekan.
Download 26.55 Kb.

Do'stlaringiz bilan baham:




Ma'lumotlar bazasi mualliflik huquqi bilan himoyalangan ©fayllar.org 2024
ma'muriyatiga murojaat qiling