DCT JAVA
来源:互联网 发布:百变小樱手办淘宝 编辑:程序博客网 时间:2024/06/05 20:23
package myjavacode;/** * DCT - A Java implementation of the Discreet Cosine Transform * * The discreet cosine transform converts spatial information to "frequency" or * spectral information, with the X and Y axes representing frequencies of the * signal in different dimensions. This allows for "lossy" compression of image * data by determining which information can be thrown away without compromising * the image.<br><br> * The DCT is used in many compression and transmission codecs, such as JPEG, MPEG * and others. The pixels when transformed are arraged from the most signifigant pixel * to the least signifigant pixel. The DCT functions themselves are lossless. * Pixel loss occurs when the least signifigant pixels are quantitized to 0. * <br><br> * This is NOT a JPEG or JFIF compliant implementation however it could * be with very little extra work. (i.e. A huffman encoding stage needs * to be added.) I am making this source availible in the hopes that * someone will add this functionality to the class, if you do, please * email me! As always, if you have any problems feel free to contact * me. (Or comments, or praise, etc..) * <br><br> * <b>Keep in mind</b> that when compressing color images with this, you will * need to break the image up into it's R G B components and preform * the calculations three times!! * <br><br> * <b>A general algorithim for DCT compression with this class:</b> <br><br> * 1) Create a DCT Object.<br> * 2) Set up your program to read pixel information in 8*8 blocks. See example.<br> * 3) Run the forwardDCT() on all blocks.<br> * 4) Run the quantitizeImage() on all blocks.<br> * 5) If you want, send the information to the imageCompressor().<br><br> * <b>A general algorithim for DCT decompression with this class:</b> <br><br> * 1) Create a DCT Object. <br> * 2) Set up the program to convert compressed data in 8*8 blocks. (if compressed)<br> * 3) Run the data through dequantitizeImage(). <br> * 4) Run the data through inverseDCT().<br> * <br><br> * A complete implementation of an image compressor which compares * the quality of the two images is also availible. See the * JEncode/Decode <a href="JEncode.java">source code.</a> The * <a href="DCT.java">DCT.java source code</a> is also availible. * The implementation is also handy for seeing how to break the image * down, read in 8x8 blocks, and reconstruct it. The <a href="steve.jpg"> * sample graphic</a> is handy to have too. (Bad pic of me) * The best way to get ahold of me is through my * <a href="http://eagle.uccb.ns.ca/steve/home.html">homepage</a>. There's * lots of goodies there too. * @version 1.0.1 August 22nd 1996 * @author <a href="http://eagle.uccb.ns.ca/steve/home.html">Stephen Manley</a> - smanley@eagle.uccb.ns.ca */public class DCT{ /** * DCT Block Size - default 8 */ public int N = 8; /** * Image Quality (0-25) - default 25 (worst image / best compression) */ public int QUALITY = 25; /** * Image width - must correspond to imageArray bounds - default 320 */ public int ROWS = 320; /** * Image height - must correspond to imageArray bounds - default 200 */ public int COLS = 240; /** * The ZigZag matrix. */ public int zigZag[][] = new int[64][2]; /** * Cosine matrix. N * N. */ public double c[][] = new double[N][N]; /** * Transformed cosine matrix, N*N. */ public double cT[][] = new double[N][N]; /** * Quantitization Matrix. */ public int quantum[][] = new int[N][N]; /** * DCT Result Matrix */ public int resultDCT[][] = new int[ROWS][COLS]; /** * Constructs a new DCT object. Initializes the cosine transform matrix * these are used when computing the DCT and it's inverse. This also * initializes the run length counters and the ZigZag sequence. Note that * the image quality can be worse than 25 however the image will be * extemely pixelated, usually to a block size of N. * * @param QUALITY The quality of the image (0 best - 25 worst) * */ public DCT(int QUALITY) { initZigZag(); initMatrix(QUALITY); } /** * This method sets up the quantization matrix using the Quality parameter * and then sets up the Cosine Transform Matrix and the Transposed CT. * These are used by the forward and inverse DCT. The RLE encoding * variables are set up to track the number of consecutive zero values * that have output or will be input. * @param quality The quality scaling factor */ private void initMatrix(int quality) { int i; int j; for (i = 0; i < N; i++) { for (j = 0; j < N; j++) { quantum[i][j] = (1 + ((1 + i + j) * quality)); } } for (j = 0; j < N; j++) { double nn = (double)(N); c[0][j] = 1.0 / Math.sqrt(nn); cT[j][0] = c[0][j]; } for (i = 1; i < 8; i++) { for (j = 0; j < 8; j++) { double jj = (double)j; double ii = (double)i; c[i][j] = Math.sqrt(2.0/8.0) * Math.cos(((2.0 * jj + 1.0) * ii * Math.PI) / (2.0 * 8.0)); cT[j][i] = c[i][j]; } } } /** * Initializes the ZigZag matrix. */ private void initZigZag() { zigZag[0][0] = 0; // 0,0 zigZag[0][1] = 0; zigZag[1][0] = 0; // 0,1 zigZag[1][1] = 1; zigZag[2][0] = 1; // 1,0 zigZag[2][1] = 0; zigZag[3][0] = 2; // 2,0 zigZag[3][1] = 0; zigZag[4][0] = 1; // 1,1 zigZag[4][1] = 1; zigZag[5][0] = 0; // 0,2 zigZag[5][1] = 2; zigZag[6][0] = 0; // 0,3 zigZag[6][1] = 3; zigZag[7][0] = 1; // 1,2 zigZag[7][1] = 2; zigZag[8][0] = 2; // 2,1 zigZag[8][1] = 1; zigZag[9][0] = 3; // 3,0 zigZag[9][1] = 0; zigZag[10][0] = 4; // 4,0 zigZag[10][1] = 0; zigZag[11][0] = 3; // 3,1 zigZag[11][1] = 1; zigZag[12][0] = 2; // 2,2 zigZag[12][1] = 2; zigZag[13][0] = 1; // 1,3 zigZag[13][1] = 3; zigZag[14][0] = 0; // 0,4 zigZag[14][1] = 4; zigZag[15][0] = 0; // 0,5 zigZag[15][1] = 5; zigZag[16][0] = 1; // 1,4 zigZag[16][1] = 4; zigZag[17][0] = 2; // 2,3 zigZag[17][1] = 3; zigZag[18][0] = 3; // 3,2 zigZag[18][1] = 2; zigZag[19][0] = 4; // 4,1 zigZag[19][1] = 1; zigZag[20][0] = 5; // 5,0 zigZag[20][1] = 0; zigZag[21][0] = 6; // 6,0 zigZag[21][1] = 0; zigZag[22][0] = 5; // 5,1 zigZag[22][1] = 1; zigZag[23][0] = 4; // 4,2 zigZag[23][1] = 2; zigZag[24][0] = 3; // 3,3 zigZag[24][1] = 3; zigZag[25][0] = 2; // 2,4 zigZag[25][1] = 4; zigZag[26][0] = 1; // 1,5 zigZag[26][1] = 5; zigZag[27][0] = 0; // 0,6 zigZag[27][1] = 6; zigZag[28][0] = 0; // 0,7 zigZag[28][1] = 7; zigZag[29][0] = 1; // 1,6 zigZag[29][1] = 6; zigZag[30][0] = 2; // 2,5 zigZag[30][1] = 5; zigZag[31][0] = 3; // 3,4 zigZag[31][1] = 4; zigZag[32][0] = 4; // 4,3 zigZag[32][1] = 3; zigZag[33][0] = 5; // 5,2 zigZag[33][1] = 2; zigZag[34][0] = 6; // 6,1 zigZag[34][1] = 1; zigZag[35][0] = 7; // 7,0 zigZag[35][1] = 0; zigZag[36][0] = 7; // 7,1 zigZag[36][1] = 1; zigZag[37][0] = 6; // 6,2 zigZag[37][1] = 2; zigZag[38][0] = 5; // 5,3 zigZag[38][1] = 3; zigZag[39][0] = 4; // 4,4 zigZag[39][1] = 4; zigZag[40][0] = 3; // 3,5 zigZag[40][1] = 5; zigZag[41][0] = 2; // 2,6 zigZag[41][1] = 6; zigZag[42][0] = 1; // 1,7 zigZag[42][1] = 7; zigZag[43][0] = 2; // 2,7 zigZag[43][1] = 7; zigZag[44][0] = 3; // 3,6 zigZag[44][1] = 6; zigZag[45][0] = 4; // 4,5 zigZag[45][1] = 5; zigZag[46][0] = 5; // 5,4 zigZag[46][1] = 4; zigZag[47][0] = 6; // 6,3 zigZag[47][1] = 3; zigZag[48][0] = 7; // 7,2 zigZag[48][1] = 2; zigZag[49][0] = 7; // 7,3 zigZag[49][1] = 3; zigZag[50][0] = 6; // 6,4 zigZag[50][1] = 4; zigZag[51][0] = 5; // 5,5 zigZag[51][1] = 5; zigZag[52][0] = 4; // 4,6 zigZag[52][1] = 6; zigZag[53][0] = 3; // 3,7 zigZag[53][1] = 7; zigZag[54][0] = 4; // 4,7 zigZag[54][1] = 7; zigZag[55][0] = 5; // 5,6 zigZag[55][1] = 6; zigZag[56][0] = 6; // 6,5 zigZag[56][1] = 5; zigZag[57][0] = 7; // 7,4 zigZag[57][1] = 4; zigZag[58][0] = 7; // 7,5 zigZag[58][1] = 5; zigZag[59][0] = 6; // 6,6 zigZag[59][1] = 6; zigZag[60][0] = 5; // 5,7 zigZag[60][1] = 7; zigZag[61][0] = 6; // 6,7 zigZag[61][1] = 7; zigZag[62][0] = 7; // 7,6 zigZag[62][1] = 6; zigZag[63][0] = 7; // 7,7 zigZag[63][1] = 7; } /** * This method preforms a matrix multiplication of the input pixel data matrix * by the transposed cosine matrix and store the result in a temporary * N * N matrix. This N * N matrix is then multiplied by the cosine matrix * and the result is stored in the output matrix. * * @param input The Input Pixel Matrix * @returns output The DCT Result Matrix */ public int[][] forwardDCT(char input[][]) { int output[][] = new int[N][N]; double temp[][] = new double[N][N]; double temp1; int i; int j; int k; for (i = 0; i < N; i++) { for (j = 0; j < N; j++) { temp[i][j] = 0.0; for (k = 0; k < N; k++) { temp[i][j] += (((int)(input[i][k]) - 128) * cT[k][j]); } } } for (i = 0; i < N; i++) { for (j = 0; j < N; j++) { temp1 = 0.0; for (k = 0; k < N; k++) { temp1 += (c[i][k] * temp[k][j]); } output[i][j] = (int)Math.round(temp1); } } return output; } /** * This method reads in DCT codes dequanitizes them * and places them in the correct location. The codes are stored in the * zigzag format so they need to be redirected to a N * N block through * simple table lookup. After dequantitization the data needs to be * run through an inverse DCT. * * @param inputData 8x8 Array of quantitized image data * @param zigzag Boolean switch to enable/disable zigzag path. * @returns outputData A N * N array of de-quantitized data * */ public int[][] dequantitizeImage(int[][] inputData, boolean zigzag) { int i = 0; int j = 0; int row; int col; int outputData[][] = new int[N][N]; double result; if (zigzag) { for (i=0; i<(N*N); i++) { row = zigZag[i][0]; col = zigZag[i][1]; result = inputData[row][col] * quantum[row][col]; outputData[row][col] = (int)(Math.round(result)); } } else { for (i=0; i<8; i++) { for (j=0; j<8; j++) { result = inputData[i][j] * quantum[i][j]; outputData[i][j] = (int)(Math.round(result)); } } } return outputData; } /** * This method orders the DCT result matrix into a zigzag pattern and then * quantitizes the data. The quantitized value is rounded to the nearest integer. * Pixels which round or divide to zero are the loss associated with * quantitizing the image. These pixels do not display in the AWT. (null) * Long runs of zeros and the small ints produced through this technique * are responsible for the small image sizes. For block sizes < or > 8, * disable the zigzag optimization. If zigzag is disabled on encode it * must be disabled on decode as well. * * @param inputData 8x8 array of DCT image data. * @param zigzag Boolean switch to enable/disable zigzag path. * @returns outputData The quantitized output data */ public int[][] quantitizeImage(int inputData[][], boolean zigzag) { int outputData[][] = new int[N][N]; int i = 0; int j = 0; int row; int col; double result; if (zigzag) { for (i = 0; i < (N*N); i++) { row = zigZag[i][0]; col = zigZag[i][1]; result = (inputData[row][col] / quantum[row][col]); outputData[row][col] = (int)(Math.round(result)); } } else { for (i=0; i<N; i++) { for (j=0; j<N; j++) { result = inputData[i][j] / quantum[i][j]; outputData[i][j] = (int)(Math.round(result)); } } } return outputData; } /** * <br><br> * This does not huffman code, * it uses a minimal run-length encoding scheme. Huffman, Adaptive Huffman * or arithmetic encoding will give much better preformance. The information * accepted is quantitized DCT data. The output array should be * scanned to determine where the end is. * * @param image Quantitized image data. * @returns The string representation of the image. (Compressed) */ public int[] compressImage(int[] QDCT, boolean log) { int i = 0; int j = 0; int k = 0; int temp = 0; @SuppressWarnings("unused")int curPos = 0; int runCounter = 0; int imageLength = ROWS*COLS; int pixel[] = new int[ROWS*COLS]; while((i<imageLength)) { temp = QDCT[i]; while((i < imageLength) && (temp == QDCT[i])) { runCounter++; i++; } if (runCounter > 4) { pixel[j] = 255; j++; pixel[j] = temp; j++; pixel[j] = runCounter; j++; } else { for (k=0; k<runCounter; k++) { pixel[j] = temp; j++; } } if (log) { System.out.print("." + "\r"); } runCounter = 0; //i++; } return pixel; } /** * This method determines the runs in the input data, decodes it * and then returnss the corrected matrix. It is used to decode the data * from the compressImage method. Huffman encoding, Adaptive Huffman or * Arithmetic will give much better compression. * * @param DCT Compressed DCT int array (Expands to whole image). * @returns The decompressed one dimensional array. */ public int[] decompressImage(int[] DCT, boolean log) { int i = 0; int j = 0; int k = 0; int temp = 0; int imageLength = ROWS*COLS; int pixel[] = new int[ROWS*COLS]; while (i < imageLength) { temp = DCT[i]; if (k < imageLength) { if (temp == 255) { i++; int value = DCT[i]; i++; int length = DCT[i]; for(j=0; j<length; j++) { pixel[k] = value; k++; } } else { pixel[k] = temp; k++; } } if (log) { System.out.print(".." + "\r"); } i++; } for (int a = 0; a < 80; a++) { System.out.print(pixel[a] + " "); } System.out.println(); for (int a = 0; a < 80; a++) { System.out.print(DCT[a] + " "); } return pixel; } /** * This method is preformed using the reverse of the operations preformed in * the DCT. This restores a N * N input block to the corresponding output * block with values scaled to 0 to 255 and then stored in the input block * of pixels. * * @param input N * N input block * @returns output The pixel array output */ public int[][] inverseDCT(int input[][]) { int output[][] = new int[N][N]; double temp[][] = new double[N][N]; double temp1; int i; int j; int k; for (i=0; i<N; i++) { for (j=0; j<N; j++) { temp[i][j] = 0.0; for (k=0; k<N; k++) { temp[i][j] += input[i][k] * c[k][j]; } } } for (i=0; i<N; i++) { for (j=0; j<N; j++) { temp1 = 0.0; for (k=0; k<N; k++) { temp1 += cT[i][k] * temp[k][j]; } temp1 += 128.0; if (temp1 < 0) { output[i][j] = 0; } else if (temp1 > 255) { output[i][j] = 255; } else { output[i][j] = (int)Math.round(temp1); } } } return output; } /** * This method uses bit shifting to convert an array of two bytes * to a integer (16 bits max). Byte 0 is the most signifigant byte * and Byte 1 is the least signifigant byte. * @param bitSet Two bytes to convert * @returns The constructed integer */ @SuppressWarnings("unused")private int bytetoInt(byte bitSet[]) { int returnInt = 0; byte MSB = bitSet[0]; byte LSB = bitSet[1]; returnInt = ((MSB+128) << 8) | (LSB+128); return returnInt; } /** * This method uses bit shifting to convert an integer to an array * of two bytes, byte 0, the most signifigant and byte 1, the least * signifigant. * @param count The integer to convert. (16 bit max) * @returns The array of two bytes. */ @SuppressWarnings("unused")private byte[] inttoByte(int count) { int LSB = 0; int MSB = 0; byte bitSet[] = new byte[2]; if (!(count > 65535)) { LSB = ((count & 0x000000ff)); MSB = ((count & 0x0000ff00) >> 8); } else { System.out.println("Integer > than 16 bit. Exiting.."); System.exit(count); } bitSet[0] = (byte)(MSB-128); bitSet[1] = (byte)(LSB-128); return bitSet; }}
0 0
- DCT JAVA
- DCT加密(Java((伪
- DCT变换(JAVA)
- dct
- DCT蝶形运算java实现
- DCT FFT
- DCT变换
- DCT变换
- DCT变换
- DCT / IDCT
- DCT变换
- dct变换
- DCT变换
- DCT变换
- dct变换
- DCT变换
- DCT变换
- DCT变换
- 使用 OpenSSL API 进行安全编程
- 【LeetCode】Two Sum
- 百度搜索上线安全联盟侵权举报中心
- java学习总结——第十一天
- 避免头文件的多重包含
- DCT JAVA
- java中与网络相关的类
- 安装Rhythmbox mp3插件
- Windows学习心得【计时器1】
- hdu 1596 find the safest road 解题报告
- 百度有意退出安全联盟 继续保护钓鱼网站利益?
- Java TimerTask
- cuda学习
- 从女人到认证