offline
- N1k0l4
- Prijatelj foruma
- Pridružio: 06 Sep 2005
- Poruke: 3800
- Gde živiš: Beograd
|
Radio sam u C# obradu fotografija, tacnije FFT sam koristio kod kompresije slika kod DCT, ako ti to znaci, evo ti kod:
private void toolStripButton10_Click(object sender, EventArgs e)
{
radna = new Bitmap(slika);
int height = radna.Height;
int width = radna.Width;
int stepen = Int16.Parse(dctStepen.Text.ToString());
if (stepen > 80)
stepen = 80;
else if (stepen < 0)
stepen = 1;
// originali
int[,] nizR = new int[height, width];
int[,] nizG = new int[height, width];
int[,] nizB = new int[height, width];
BitmapData bmpData = radna.LockBits(new Rectangle(0, 0, width, height), ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);
IntPtr ptr = bmpData.Scan0;
int bytes = Math.Abs(bmpData.Stride) * height;
byte[] rgbValues = new byte[bytes];
System.Runtime.InteropServices.Marshal.Copy(ptr, rgbValues, 0, bytes);
int i, j, w;
for (i = 0; i < height; i++)
{
int poz = i * bmpData.Stride;
for (j = 0, w = 0; j < width * 3; j += 3, w++)
{
int poz_blue = poz + j;
int poz_green = poz + j + 1;
int poz_red = poz + j + 2;
nizB[i, w] = rgbValues[poz_blue];
nizG[i, w] = rgbValues[poz_green];
nizR[i, w] = rgbValues[poz_red];
}
}
//8x8
int n = height / 8;
int m = width / 8;
Matrica MR = null;
Matrica MG = null;
Matrica MB = null;
for (i = 0; i < n; i++)
for (j = 0; j < m; j++)
{
MR = DCT_obrada(new Matrica(nizR, i * 8, j * 8), stepen);
Matrica.ubaciUNiz(nizR, i * 8, j * 8, MR);
MG = DCT_obrada(new Matrica(nizG, i * 8, j * 8), stepen);
Matrica.ubaciUNiz(nizG, i * 8, j * 8, MG);
MB = DCT_obrada(new Matrica(nizB, i * 8, j * 8), stepen);
Matrica.ubaciUNiz(nizB, i * 8, j * 8, MB);
}
// prikaz slike
for (i = 0; i < height; i++)
{
int poz = i * bmpData.Stride;
for (j = 0, w = 0; j < width * 3; j += 3, w++)
{
int poz_blue = poz + j;
int poz_green = poz + j + 1;
int poz_red = poz + j + 2;
rgbValues[poz_blue] = (byte)nizB[i, w];
rgbValues[poz_green] = (byte)nizG[i, w];
rgbValues[poz_red] = (byte)nizR[i, w];
}
}
System.Runtime.InteropServices.Marshal.Copy(rgbValues, 0, ptr, bytes);
radna.UnlockBits(bmpData);
pictureBox1.Image = radna;
}
klasa matrica:
class Matrica
{
private double[,] _matEl = new double[8, 8];
public Matrica(double[,] A)
{
int i, j;
double[,] a = new double[8, 8];
for (i = 0; i < 8; i++)
for (j = 0; j < 8; j++)
a[i, j] = A[i, j];
this._matEl = a;
}
public Matrica()
{
int i, j;
double[,] a = new double[8, 8];
for (i = 0; i < 8; i++)
for (j = 0; j < 8; j++)
a[i, j] = 0.0;
this._matEl = a;
}
public double element(int i, int j)
{
return this._matEl[i, j];
}
public void postaviElement(double a, int i, int j)
{
this._matEl[i, j] = a;
}
public Matrica pomnoziMatrice(Matrica Mr, int ind)
{
if (ind == 1) // levo
{
Matrica priv = new Matrica();
int i, j, k;
double S;
for (i = 0; i < 8; i++)
for (j = 0; j < 8; j++)
{
S = 0;
for (k = 0; k < 8; k++)
{
S = S + Mr.element(i, k) * this._matEl[k, j];
}
priv.postaviElement(S, i, j);
}
return priv;
}
else //desno
{
Matrica priv = new Matrica();
int i, j, k;
double S;
for (i = 0; i < 8; i++)
for (j = 0; j < 8; j++)
{
S = 0;
for (k = 0; k < 8; k++)
{
S = S + this._matEl[i, k] * Mr.element(k, j);
}
priv.postaviElement(S, i, j);
}
return priv;
}
}
public Matrica transponovana()
{
int i, j;
double[,] a = new double[8, 8];
for (i = 0; i < 8; i++)
for (j = 0; j < 8; j++)
a[j, i] = this.element(i, j);
return new Matrica(a);
}
public Matrica skaliraj() //{-127,128}
{
int i, j;
double[,] a = new double[8, 8];
for (i = 0; i < 8; i++)
for (j = 0; j < 8; j++)
a[i, j] = this.element(i, j) - 128;
return new Matrica(a);
}
public Matrica skaliraj2() //{0,256}
{
int i, j;
double[,] a = new double[8, 8];
for (i = 0; i < 8; i++)
for (j = 0; j < 8; j++)
a[i, j] = this.element(i, j) + 128;
return new Matrica(a);
}
public Matrica getQuantization(int stepen)
{
if (stepen > 50)
{
int i, j;
double[,] a = new double[8, 8];
for (i = 0; i < 8; i++)
for (j = 0; j < 8; j++)
a[i, j] = (int)Math.Round(this.element(i, j) * ((100 - stepen) / 50.0));
return new Matrica(a);
}
else
{
int i, j;
double[,] a = new double[8, 8];
for (i = 0; i < 8; i++)
for (j = 0; j < 8; j++)
a[i, j] = (int)Math.Round(this.element(i, j) * (float)(50 / stepen));
return new Matrica(a);
}
}
public Matrica(int[,] Niz, int poc_x, int poc_y)
{
int i, j;
for (i = 0; i < 8; i++)
for (j = 0; j < 8; j++)
this._matEl[i, j] = Niz[poc_x + i, poc_y + j];
}
static public void ubaciUNiz(int[,] velNiz, int poc_x, int poc_y, Matrica A)
{
int i, j, x;
for (i = 0; i < 8; i++)
for (j = 0; j < 8; j++)
{
x = (int)Math.Round(A.element(i, j));
if (x > 255) { x = 255; }
else if (x < 0) { x = 0; }
velNiz[poc_x + i, poc_y + j] = x;
}
}
}
private Matrica DCT_obrada(Matrica Original, int stepen)
{
int i, j;
double[,] nT = {{0.3536, 0.3536, 0.3536, 0.3536, 0.3536, 0.3536, 0.3536, 0.3536},
{0.4904, 0.4157, 0.2778, 0.0975, -0.0975, -0.2778, -0.4157, -0.4904},
{0.4619, 0.1913, -0.1913, -0.4619, -0.4619, -0.1913, 0.1913, 0.4619},
{0.4157, -0.0975, -0.4904, -0.2778, 0.2778, 0.4904, 0.0975, -0.4157},
{0.3536, -0.3536, -0.3536, 0.3536, 0.3536, -0.3536, -0.3536, 0.3536},
{0.2778, -0.4904, 0.0975, 0.4157, -0.4157, -0.0975, 0.4904, -0.2778},
{0.1913, -0.4619, 0.4619, -0.1913, -0.1913, 0.4619, -0.4619, 0.1913},
{0.0975, -0.2778, 0.4157, -0.4904, 0.4904, -0.4157, 0.2778, -0.0975}};
Matrica T = new Matrica(nT);
Matrica Tt = T.transponovana();
double[,] nQ50 = {{16, 11, 10, 16, 24, 40, 51, 61},
{12, 12, 14, 19, 26, 58, 60, 55},
{14, 13, 16, 24, 40, 57, 69, 56},
{14, 17, 22, 29, 51, 87, 80, 62},
{18, 22, 37, 56, 68, 109, 103, 77},
{24, 35, 55, 64, 81, 104, 113, 92},
{49, 64, 78, 87, 103, 121, 120, 101},
{72, 92, 95, 98, 112, 100, 103, 99}};
Matrica Q_50 = new Matrica(nQ50);
Matrica Q = null;
if (stepen != 50)
{
Q = Q_50.getQuantization(stepen);
}
else
{ Q = Q_50; };
Matrica C = new Matrica();
Matrica M = Original.skaliraj(); // [-128, 127]
M = M.pomnoziMatrice(T,1);
M = M.pomnoziMatrice(Tt,2);
for (i = 0; i < 8; i++)
for (j = 0; j < 8; j++)
C.postaviElement(Math.Round(M.element(i, j) / Q.element(i, j)), i, j);
for (i = 0; i < 8; i++)
for (j = 0; j < 8; j++)
{
double e = C.element(i, j) * Q.element(i, j);
C.postaviElement(e, i, j);
}
C = C.pomnoziMatrice(T,2);
C = C.pomnoziMatrice(Tt,1);
C= C.skaliraj2(); // 0,256
for (i = 0; i < 8; i++)
for (j = 0; j < 8; j++)
C.postaviElement(Math.Round(C.element(i, j)), i, j);
return C;
}
|