DWSOFT
离散余弦变换(DCT)
C#版
*******************************************************************************
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace DCT
{
class Program
{
static void Main(string[] args)
{
Planar p = new Planar();
int[,] ia = p.GetArray();
Console.WriteLine("The matrix of eight multiply eitht is:");
Display(ia);
FDCT f = new FDCT();
int[,] ia2 = f.Fdct(p);
Console.WriteLine("用 DCT 把样值矩阵变换为频域矩阵之后:");
Display(ia2);
Quantize q = new Quantize();
int[,] ia3 = q.Quan(f,p);
Console.WriteLine("除以量化表值,再取整后得到的量化矩阵:");
Display(ia3);
ZigZag z = new ZigZag();
int[] ia4 = z.Zig(q,f,p);
Console.WriteLine("使用 Zig-Zag 方法扫描得到的一维序列:");
for (int i = 0; i < ia4.Length-1; i++)
Console.Write(ia4[i] + ",");
Console.Write(ia4[ia4.Length - 1]+"\n");
Console.ReadKey();
}
static void Display(int[,] ia)//定义一个输出方法
{
for (int i = 0; i < 8; i++)
{
for (int j = 0; j < 8; j++)
Console.Write(ia[i, j] + "\t");
Console.WriteLine("\n");
}
DWSOFT
DWSOFT
}
public class FDCT//正向 DCT 变换类
}
{
public int UArray { get; set; }
public int VArray { get; set; }
public int[,] Fdct(Planar p)
{
int[,] ia=new int[8,8];
int[,] ia2=p.GetArray();
double k;//此值为原公式中的 C(u)C(v)/4
if (UArray == 0 && VArray == 0)
k = Math.Sqrt(2) / 8;
else
k = 0.25;
for(int i=0;i<8;i++)
for(int j=0;j<8;j++)
{
//由于 UArray=XArray=i;VArray=YArray=j;故直接用 i,j 代替
double d1=Math.Cos((2*i+1)*i*Math.PI/16);
double d2=Math.Cos((2*j+1)*j*Math.PI/16);
ia[i, j] = (int)(k * ia2[i, j] * d1 * d2);
}
return ia;
}
}
public class Planar//样值空间类
{
public int XArray { get; set; }
public int YArray { get; set; }
///
/// 得到 8*8 的 int 二维数组
///
///
public int[,] GetArray()
{
Random r = new Random();
int[,] ia = new int[8, 8];
for (XArray = 0; XArray < 8; XArray++)
{
for (YArray = 0; YArray < 8; YArray++)
{
DWSOFT
DWSOFT
ia[XArray, YArray] = r.Next(256);
}
}
return ia;
}
}
class Quantize//量化矩阵类
{
public int[,] Quan(FDCT f,Planar p)
{
int[,] ia = f.Fdct(p);
for(int i=0;i<8;i++)
for (int j = 0; j < 8; j++)
{
if (i == 0 && j == 0)
ia[i, j] /= 17;
else if (i == 0 && j == 1)
ia[i, j] /= 18;
else if (i == 0 && j == 2)
ia[i, j] /= 24;
else if (i == 0 && j == 3)
ia[i, j] /= 47;
else if (i == 1 && j == 0)
ia[i, j] /= 18;
else if (i == 1 && j == 1)
ia[i, j] /= 21;
else if (i == 1 && j == 2)
ia[i, j] /= 26;
else if (i == 1 && j == 3)
ia[i, j] /= 66;
else if (i == 2 && j == 0)
ia[i, j] /= 24;
else if (i == 2 && j == 1)
ia[i, j] /= 26;
else if (i == 2 && j == 2)
ia[i, j] /= 56;
else if (i == 3 && j == 0)
ia[i, j] /= 47;
else if (i == 3 && j == 1)
ia[i, j] /= 66;
else
ia[i, j] /= 99;
}
DWSOFT
DWSOFT
return ia;
}
}
class ZigZag//Zig-Zag 扫描类
{
public int[] Zig(Quantize q,FDCT f,Planar p)
{
int[,] ia = q.Quan(f,p);
int[] ia1=new int[64];
int m=0;
for (int k = 0; k <= 14; k++)
{
for (int i = 0; i < 8; i++)
for (int j = 0; j < 8; j++)
if (i + j == k)
ia1[m++] = ia[i, j];
}
return ia1;
}
}
}
DWSOFT