package com.imageretrieval.features;
import java.awt.Color;
import com.imageretrieval.utils.HSV;
import com.imageretrieval.utils.Pixel;
/**
* 该颜色直方图更接近于人类对图片的识别程度
* @author VenyoWang
*
*/
public class HSVColorHistogram {
public static void main(String[] args) {
Pixel[][] matrix = getImagePixel("", 200, 200);
Pixel[][] matrix1 = getImagePixel("", 200, 200);
HSV[][] hsvMatrix = new HSV[matrix.length][];
HSV[][] hsvMatrix1 = new HSV[matrix1.length][];
for(int i = 0; i < matrix.length; i++){
hsvMatrix[i] = new HSV[matrix[i].length];
hsvMatrix1[i] = new HSV[matrix1[i].length];
for(int j = 0; j < matrix[i].length; j++){
float[] fs = Color.RGBtoHSB(matrix[i][j].red, matrix[i][j].green, matrix[i][j].blue, null);
HSV hsv = new HSV();
hsv.h = (int)(fs[0] * 255);
hsv.s = (int)(fs[1] * 255);
hsv.v = (int)(fs[2] * 255);
hsvMatrix[i][j] = hsv;
fs = Color.RGBtoHSB(matrix1[i][j].red, matrix1[i][j].green, matrix1[i][j].blue, null);
hsv = new HSV();
hsv.h = (int)(fs[0] * 255);
hsv.s = (int)(fs[1] * 255);
hsv.v = (int)(fs[2] * 255);
hsvMatrix1[i][j] = hsv;
}
}
int[][] histogram = new int[3][256];
int[][] histogram1 = new int[3][256];
for(int i = 0; i < hsvMatrix.length; i++){
for(int j = 0; j < hsvMatrix[0].length; j++){
histogram[0][hsvMatrix[i][j].h]++;
histogram[1][hsvMatrix[i][j].s]++;
histogram[2][hsvMatrix[i][j].v]++;
histogram1[0][hsvMatrix1[i][j].h]++;
histogram1[1][hsvMatrix1[i][j].s]++;
histogram1[2][hsvMatrix1[i][j].v]++;
}
}
int[] vector = Util.matrix2vector(histogram);
int[] vector1 = Util.matrix2vector(histogram1);
System.out.println(calculateSimilarity(vector, vector1));
}
public static Pixel[][] getImagePixel(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();
Pixel[][] rgbMatrix = new Pixel[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);
Pixel p = new Pixel();
p.red = red;
p.green = green;
p.blue = blue;
rgbMatrix[i - minx][j - miny] = p;
}
}
return rgbMatrix;
}
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;
}
public static double calculateSimilarity(int[] vector, int[] vector1) {
double len = 0, len1 = 0, numerator = 0;
for (int i = 0; i < vector.length; i++) {
len += Math.pow(vector[i], 2);
len1 += Math.pow(vector1[i], 2);
numerator += vector[i] * vector1[i];
}
len = Math.sqrt(len);
len1 = Math.sqrt(len1);
return numerator / (len * len1);
}
public static int[] matrix2vector(int[][] matrix){
if(matrix.length <= 0 || matrix[0].length <= 0){
return null;
}
int[] vector = new int[matrix.length * matrix[0].length];
int index = 0;
for(int i = 0; i < matrix.length; i++){
for(int j = 0; j < matrix[0].length; j++, index++){
vector[index] = matrix[i][j];
}
}
return vector;
}
}