Last active
March 3, 2017 04:05
-
-
Save zhiyue/8a22d3b68f179412f262 to your computer and use it in GitHub Desktop.
离散余弦变换 #
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import java.io.IOException; | |
public class DctTrans { | |
// * in_image 输入图像矩阵 | |
// * iw, ih 输入图像宽高 | |
// * bsize bsizeXbsize图像块DCT变换 | |
// * type type = 1为正DCT变换, type =-1为逆变换 | |
// *------------------------------------------------------------*/ | |
public double[][] dct_image; | |
public double[][] dct_coef; | |
public double[][] dct_coeft; | |
public double[][] image; | |
public double[][] dctTrans(double[][] img, int iw, int ih, int bsize, int type) | |
{ | |
int iter_num = 256 / bsize; | |
dct_image = new double[iw][ih]; | |
dct_coef = new double[bsize][bsize]; | |
dct_coeft = new double[bsize][bsize]; | |
image = new double[bsize][bsize]; | |
coeff(dct_coef, bsize); | |
//定义转置矩阵系数 | |
for (int i = 0; i < bsize; i++) | |
for (int j = 0; j < bsize; j++) | |
dct_coeft[i][j] = dct_coef[j][i]; | |
if (type == 1) | |
{ | |
for (int j = 0; j < iter_num; j++) | |
{ | |
for (int i = 0; i < iter_num; i++) | |
{ | |
//取bsizeXbsize图像块image[][] | |
for (int k = 0; k < bsize; k++) | |
for (int l = 0; l < bsize; l++) | |
image[k][l] = img[i * bsize + k][j * bsize + l]; | |
//bsizeXbsize块DCT变换 | |
dct(image, dct_coeft, dct_coef, bsize);//正变换 | |
//Output dct image | |
for (int k = 0; k < bsize; k++) | |
for (int l = 0; l < bsize; l++) | |
dct_image[i * bsize + k][j * bsize + l] = image[k][l]; | |
} | |
} | |
} | |
else | |
{ | |
for (int j = 0; j < iter_num; j++) | |
{ | |
for (int i = 0; i < iter_num; i++) | |
{ | |
//取bsizeXbsize图像块image[,] | |
for (int k = 0; k < bsize; k++) | |
for (int l = 0; l < bsize; l++) | |
image[k][l] = img[i * bsize + k][j * bsize + l]; | |
//bsizeXbsize块IDCT变换 | |
dct(image, dct_coef, dct_coeft, bsize);//逆变换 | |
//Output dct image | |
for (int k = 0; k < bsize; k++) | |
for (int l = 0; l < bsize; l++) | |
dct_image[i * bsize + k][j * bsize + l] = image[k][l]; | |
} | |
} | |
} | |
return dct_image; | |
} | |
public void coeff(double[][] dct_coef, int n) | |
{ | |
double sqrt_1 = 1.0 / Math.sqrt(2.0); | |
for (int i = 0; i < n; i++) | |
dct_coef[0][i] = sqrt_1; | |
//初始化DCT系数 | |
for (int i = 1; i < n; i++) | |
for (int j = 0; j < n; j++) | |
dct_coef[i][j] = Math.cos(i * Math.PI * (j + 0.5) / ((double)n)); | |
} | |
public void dct(double[][] a, double[][] b, double[][] c, int n) | |
{ | |
double x; | |
double[][] af = new double[n][n]; | |
for (int i = 0; i < n; i++) | |
{ | |
for (int j = 0; j < n; j++) | |
{ | |
x = 0.0; | |
for (int k = 0; k < n; k++) | |
x += a[i][k] * b[k][j]; | |
af[i][j] = x; | |
} | |
} | |
for (int i = 0; i < n; i++) | |
{ | |
for (int j = 0; j < n; j++) | |
{ | |
x = 0.0; | |
for (int k = 0; k < n; k++) | |
x += c[i][k] * af[k][j]; | |
a[i][j] = 2.0 * x / ((double)n); | |
} | |
} | |
} | |
public String getImageHASHString( Block block,char code,int size,int smallerSize) throws IOException{ | |
int[][] data = block.__data; | |
double[][] vals = new double[size][size]; | |
for (int x = 0; x < data.length; x++) { | |
for (int y = 0; y < data[0].length; y++) { | |
vals[x][y] = data[x][y]; | |
} | |
} | |
/* | |
* 对获取的所有像素点的RGB值进行DCT计算 | |
* DCT算法是专门针对于图像压缩计算方法, | |
* 如果您感兴趣,请参看: | |
* http://zh.wikipedia.org/wiki/%E7%A6%BB%E6%95%A3%E4%BD%99%E5%BC%A6%E5%8F%98%E6%8D%A2 | |
*/ | |
long start = System.currentTimeMillis(); | |
double[][] dctVals = dctTrans(vals,data.length,data[0].length,data.length,1); | |
/* 重置DCT,仅仅取压缩后的全图左上角8*8 pixs的区间作为代表 | |
* (因为此区间代表了变化低频区域,那么低频区的差异性更客观地代表图片整体的匹配度) | |
*/ | |
/* | |
* 计算DCT的平均值 | |
*/ | |
double total = 0; | |
for (int x = 0; x < smallerSize; x++) { | |
for (int y = 0; y < smallerSize; y++) { | |
total += dctVals[x][y]; | |
} | |
} | |
total -= dctVals[0][0]; | |
double avg = total / (double) ((smallerSize * smallerSize) - 1); | |
/* | |
* 深度转换DCT,将结果全部组成为0/1组合队列 | |
*/ | |
String hash = ""; | |
for (int x = 0; x < smallerSize; x++) { | |
for (int y = 0; y < smallerSize; y++) { | |
/* if (x != 0 && y != 0) { | |
hash += (dctVals[x][y] > avg?"1":"0"); | |
} | |
*/ | |
hash += (dctVals[x][y] > avg?"1":"0"); | |
} | |
} | |
System.out.println("[INFO]对["+code+"]进行的DCT计算完成,耗时: " + (System.currentTimeMillis() - start)+" ms"); | |
return hash; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
ih难道用不到吗?还是说原始图片是个正方形