您的位置:首页 > 编程语言 > Java开发

旋转不变的感知哈希

2016-07-06 00:00 447 查看
摘要: 在感知哈希的基础上添加了类似LBP的旋转不变性(个人实现,旋转不变的灵感就是来自LBP)

[code=language-java]package com.imageretrieval.features;

import com.imageretrieval.utils.ImageUtil;

/**
* 旋转不变的感知哈希<br>
* @author VenyoWang
*
*/
public class RHash {

public static void main(String[] args) {
String hash = getFeatureValue("");
String hash1 = getFeatureValue("");
System.out.println(hash);
System.out.println(hash1);
System.out.println(calculateSimilarity(hash, hash1));
}

public static String getFeatureValue(String imagePath) {
// 缩小尺寸,简化色彩
int[][] grayMatrix = getGrayPixel(imagePath, 8, 8);
// 缩小DCT,计算平均值
int[][] newMatrix = new int[8][8];
double average = 0;
for(int i = 0; i < 8; i++){
for(int j = 0; j < 8; j++){
newMatrix[i][j] = grayMatrix[i][j];
average += grayMatrix[i][j];
}
}
average /= 64.0;
return getFeature(newMatrix, average);
}

/**
* 旋转不变性<br>
* @return
*/
private static String getFeature(int[][] matrix, double average) {
// 半径
String featureValue = "";
int[] r = {2, 4, 6, 8};
for(int i = 0; i < 4; i++){
// 正方形左上角的点的下标
int start = (8 - r[i]) / 2;
int feature = 0;
for(int j = start; j < start + r[i]; j++){
feature = matrix[start][j] < average ? feature<<1 : (feature<<1)+1;
}
for(int j = start + 1; j < start + r[i]; j++){
feature = matrix[j][start + r[i] - 1] < average ? feature<<1 : (feature<<1)+1;
}
for(int j = start + r[i] - 2; j >= start; j--){
feature = matrix[start + r[i] - 1][j] < average ? feature<<1 : (feature<<1)+1;
}
for(int j = start + r[i] - 2; j > start; j--){
feature = matrix[j][start] < average ? feature<<1 : (feature<<1)+1;
}
featureValue += getMinFeature(feature, 4 * (r[i] - 1));
}
return featureValue;
}

private static String getMinFeature(int feature, int bitNum) {
// 位数为bitNum的情况下的最大值
int max = 1;
for(int i = 1; i < bitNum; i++){
max = (max << 1) + 1;
}
int min = feature;
for(int i = 0; i < bitNum - 1; i++){
feature = (feature>>1 | feature<<(bitNum - 1)) & max;
if(feature < min) min = feature;
}
String result = "";
for(int i = 0; i < bitNum; i++){
if(min % 2 == 0){
result = "0" + result;
}
else {
result = "1" + result;
}
min >>= 1;
}
return result;
}

public static int[][] getGrayPixel(String imagePath, int width, int height) {
BufferedImage bi = null;
try {
bi = resizeImage(imagePath, width, height, BufferedImage.TYPE_INT_RGB);
} catch (Exception e) {
e.printStackTrace();
return null;
}
int minx = bi.getMinX();
int miny = bi.getMinY();
int[][] matrix = new int[width - minx][height - miny];
for (int i = minx; i < width; i++) {
for (int j = miny; j < height; j++) {
int pixel = bi.getRGB(i, j);
int red = (pixel & 0xff0000) >> 16;
int green = (pixel & 0xff00) >> 8;
int blue = (pixel & 0xff);
int gray = (int) (red * 0.3 + green * 0.59 + blue * 0.11);
matrix[i][j] = gray;
}
}
return matrix;
}

public static BufferedImage resizeImage(String srcImgPath, int width, int height, int imageType)
throws IOException {
File srcFile = new File(srcImgPath);
BufferedImage srcImg = ImageIO.read(srcFile);
BufferedImage buffImg = null;
buffImg = new BufferedImage(width, height, imageType);
buffImg.getGraphics().drawImage(srcImg.getScaledInstance(width, height, Image.SCALE_SMOOTH), 0, 0, null);
return buffImg;
}

/**
* 用于计算pHash的相似度<br>
* 相似度为1时,图片最相似
* @param str1
* @param str2
* @return
*/
public static double calculateSimilarity(String str1, String str2) {
int num = 0;
for(int i = 0; i < 64; i++){
if(str1.charAt(i) == str2.charAt(i)){
num++;
}
}
return ((double)num) / 64.0;
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息