Skip to content

Instantly share code, notes, and snippets.

@zhiyue
Last active March 3, 2017 04:05
Show Gist options
  • Save zhiyue/8a22d3b68f179412f262 to your computer and use it in GitHub Desktop.
Save zhiyue/8a22d3b68f179412f262 to your computer and use it in GitHub Desktop.
离散余弦变换 #
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;
}
}
@yuyedaidao
Copy link

ih难道用不到吗?还是说原始图片是个正方形

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment