주파수 영역처리 C#소스 코드(이산 코사인 변환)
주파수 영역처리 C#소스 코드(이산 코사인 변환)
- [주파수_이산코사인변환(DCT)] 메뉴를 더블클릭한 후 private void 주파수이산코사인변환DCTToolStripMenuItem_Click() 함수를 추가한다.
1234567891011121314151617181920private void 주파수이산코사인변환DCTToolStripMenuItem_Click(object sender, EventArgs e){Bitmap bmp = f_OpenBitmapFile();if (bmp == null) return;byte[] data = f_getDataFromImage(bmp);///////// Start Image Processing ////////////////if (bmp.PixelFormat != PixelFormat.Format8bppIndexed){MessageBox.Show("8bit 색상 모델만 실행 가능합니다.");return;}byte[] newdata = f_DCT_Original(data, bmp.Width, bmp.Height);///////// End Image Processing ////////////////Bitmap bmpResult = f_makeImageFromData(bmp.Width, bmp.Height, bmp.PixelFormat, newdata);f_drawImage(bmp, bmpResult);}
- f_DCT_Original() 함수를 생성한다.
순수 DCT 변환 함수 -
123456789101112131415161718192021222324252627282930313233343536373839private byte[] f_DCT_Original(byte[] inputImg, int width, int height){double[] dct = new double[inputImg.Length];for (int v = 0; v < height; v++){for (int u = 0; u < width; u++){dct[v * width + u] = 0.0;for (int y = 0; y < height; y++){for (int x = 0; x < width; x++){dct[v * width + u] += inputImg[y * width + x]* Math.Cos(((2.0 * x + 1.0) * u * Math.PI) / (2.0 * width))* Math.Cos(((2.0 * y + 1.0) * v * Math.PI) / (2.0 * height));}}dct[v * width + u] *= 2.0 / Math.Sqrt((double)(width * height));if (u == 0) dct[v * width + u] *= 1.0 / Math.Sqrt(2.0);if (v == 0) dct[v * width + u] *= 1.0 / Math.Sqrt(2.0);}}byte[] resultImg = new byte[inputImg.Length];for (int y = 0; y < height; y++){for (int x = 0; x < width; x++){int value = (int)(30 * Math.Log(1.0 + dct[y * width + x]));if (value < 0) value = 0;if (value > 255) value = 255;resultImg[y * width + x] = (byte)value;}}return resultImg;}
- [주파수_fastDCT] 메뉴를 더블클릭한 후 private void 주파수fastDCTToolStripMenuItem_Click() 함수를 추가한다.
12345678910111213141516171819private void 주파수fastDCTToolStripMenuItem_Click(object sender, EventArgs e){Bitmap bmp = f_OpenBitmapFile();if (bmp == null) return;byte[] data = f_getDataFromImage(bmp);////////////////// Startif (bmp.PixelFormat != PixelFormat.Format8bppIndexed){MessageBox.Show("8bit 색상 모델만 실행 가능합니다.");return;}double[] dct = f_DCT_Fast(data, bmp.Width, bmp.Height);byte[] newdata = f_DCT_toImage(dct, bmp.Width, bmp.Height);////////////////// EndBitmap bmpResult = f_makeImageFromData(bmp.Width, bmp.Height, newdata);f_drawImage(bmp, bmpResult);}
- f_DCT_1D() 함수를 생성한다.1차원 DCT 변환 함수 생성
12345678910111213private void f_DCT_1D(double[] in1, double[] out1, int count){for (int u = 0; u < count; u++){double z = 0;for (int x = 0; x < count; x++){z += in1[x] * Math.Cos(Math.PI * u * (2 * x + 1) / (2 * count));}if (u == 0) z = z * (1.0 / Math.Sqrt(2.0));out1[u] = z * Math.Sqrt(2.0 / count);}}
- f_DCT_2D() 함수를 생성한다.
2차원 DCT 변환 함수 생성
123456789101112131415161718192021222324252627282930313233343536373839private double[] f_DCT_Fast(byte[] data, int width, int height){double[] dct = new double[data.Length];double[] in1 = new double[height];double[] out1 = new double[width];for (int y = 0; y < height; y++){for (int x = 0; x < width; x++){in1[x] = data[y * width + x];}f_DCT_1D(in1, out1, width);for (int x = 0; x < width; x++){dct[y * width + x] = out1[x];}}double[] in2 = new double[width];double[] out2 = new double[height];for (int x = 0; x < width; x++){for (int y = 0; y < height; y++){in2[y] = dct[y * width + x];}f_DCT_1D(in2, out2, height);for (int y = 0; y < height; y++){dct[y * width + x] = out2[y];}}return dct;}
- f_DCT_toImage() 함수를 생성한다.
fastDCT 변환 후 결과를 2차원 영상으로 변환하는 함수
1234567891011121314151617private byte[] f_DCT_toImage(double[] dct, int width, int height){byte[] newdata = new byte[dct.Length];for (int y = 0; y < height; y++){for (int x = 0; x < width; x++){int value = (int)(30 * Math.Log(1.0 + dct[y * width + x]));if (value < 0) value = 0;if (value > 255) value = 255;newdata[y * width + x] = (byte)value;}}return newdata;}
- [주파수_fastIDCT] 메뉴를 더블클릭한 후 private void 주파수fastIDCTToolStripMenuItem_Click() 함수를 추가한다.
12345678910111213141516171819private void 주파수fastIDCTToolStripMenuItem_Click(object sender, EventArgs e){Bitmap bmp = f_OpenBitmapFile();if (bmp == null) return;byte[] data = f_getDataFromImage(bmp);////////////////// Startif (bmp.PixelFormat != PixelFormat.Format8bppIndexed){MessageBox.Show("8bit 색상 모델만 실행 가능합니다.");return;}double[] dct = f_DCT_Fast(data, bmp.Width, bmp.Height);double[] idct = f_IDCT_Fast(dct, bmp.Width, bmp.Height);byte[] newdata = f_IDCT_toImage(idct, bmp.Width, bmp.Height);////////////////// EndBitmap bmpResult = f_makeImageFromData(bmp.Width, bmp.Height, newdata);f_drawImage(bmp, bmpResult);}
- f_IDCT_1D() 함수를 생성한다.1차원 DCT 역변환 함수
123456789101112131415void f_IDCT_1D(double[] in1, double[] out1, int count){double cv;for (int x = 0; x < count; x++){double z = 0;for (int u = 0; u < count; u++){if (u == 0) cv = 1.0 / Math.Sqrt(2.0);else cv = 1.0;z += in1[u] * cv * Math.Cos(Math.PI * u * (2 * x + 1) / (2 * count));}out1[x] = z * Math.Sqrt(2.0 / count);}}
- f_IDCT_Fast() 함수를 생성한다.
2차원 DCT 역변환 함수
123456789101112131415161718192021222324252627282930313233343536373839private double[] f_IDCT_Fast(double[] dct, int width, int height){double[] idct = new double[dct.Length];double[] in1 = new double[height];double[] out1 = new double[width];for (int y = 0; y < height; y++){for (int x = 0; x < width; x++){in1[x] = dct[y * width + x];}f_IDCT_1D(in1, out1, width);for (int x = 0; x < width; x++){idct[y * width + x] = out1[x];}}double[] in2 = new double[width];double[] out2 = new double[height];for (int x = 0; x < width; x++){for (int y = 0; y < height; y++){in2[y] = idct[y * width + x];}f_IDCT_1D(in2, out2, height);for (int y = 0; y < height; y++){idct[y * width + x] = out2[y];}}return idct;}
- f_IDCT_toImage() 함수를 생성한다.
fastIDCT 변환 후 결과를 2차원 영상으로 변환하는 함수
1234567891011121314private byte[] f_IDCT_toImage(double[] idct, int width, int height){byte[] newdata = new byte[idct.Length];for (int y = 0; y < height; y++){for (int x = 0; x < width; x++){newdata[y * width + x] = (byte)idct[y*width+x];}}return newdata;}