## 环形颜色分布直方图 原

VenyoWang

``````package com.imageretrieval.features;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import com.imageretrieval.utils.Coordinate;
import com.imageretrieval.utils.ImageUtil;
import com.imageretrieval.utils.Util;

/**
* 环形颜色分布直方图<br>
* 参考文献：<br>
* 1pXvBz7UKzoe4iGmH4S-8j4MiuAXyzetBV7NEDwJC7BBjT8ecCpHvo7oSBNChO0gLJMhI7<br>
* oFpKL4VvFOy1r5lznMJg9rQ2dWvbzXiSoEOO_Oge0THJZF6nEedJG5hJtAGZm-cyNqSoEZW<br>
*
* @author VenyoWang
*
*/
public class AnnularColorLayoutHistogram {

/** 同心圆个数 */
private static int N = 10;

public static void main(String[] args) {
int[][] nums = getFeatureMatrix("");
int[][] nums1 = getFeatureMatrix("");
System.out.println(calculateSimilarity(Util.matrix2vector(nums), Util.matrix2vector(nums1)));
}

public static int[][] getFeatureMatrix(String imagePath) {
// 获取灰度矩阵
int[][] matrix = getGrayPixel(imagePath, 200, 200);

// 根据灰度值对像素点进行分组
Map<Integer, List<Coordinate>> groupedPixels = new HashMap<Integer, List<Coordinate>>();
for (int i = 0; i < matrix.length; i++) {
for (int j = 0; j < matrix[0].length; j++) {
List<Coordinate> list = null;
if (groupedPixels.containsKey(matrix[i][j])) {
list = groupedPixels.get(matrix[i][j]);
} else {
list = new ArrayList<Coordinate>();
}
Coordinate coordinate = new Coordinate();
coordinate.x = i;
coordinate.y = j;
groupedPixels.put(matrix[i][j], list);
}
}

// 为不同的灰度值计算质心
Coordinate[] centroid = new Coordinate[256];
for (int i = 0; i <= 255; i++) {
if (groupedPixels.containsKey(i)) {
List<Coordinate> list = groupedPixels.get(i);
double x = 0, y = 0;
for (int j = 0; j < list.size(); j++) {
Coordinate coordinate = list.get(j);
x += coordinate.x;
y += coordinate.y;
}
x = x / list.size();
y = y / list.size();
Coordinate coordinate = new Coordinate();
coordinate.x = x;
coordinate.y = y;
centroid[i] = coordinate;
}
}

// 为每一个像素计算其到质心的距离
double[][] distances = new double[matrix.length][matrix[0].length];
for (int i = 0; i < matrix.length; i++) {
for (int j = 0; j < matrix[0].length; j++) {
Coordinate coordinate = centroid[matrix[i][j]];
distances[i][j] = Math.sqrt(Math.pow(i - coordinate.x, 2) + Math.pow(j - coordinate.y, 2));
}
}

// 比较出最大距离
double[] maxDistances = new double[256];
for (int i = 0; i <= 255; i++) {
if (groupedPixels.containsKey(i)) {
List<Coordinate> list = groupedPixels.get(i);
double max = 0;
for (int j = 0; j < list.size(); j++) {
Coordinate coordinate = list.get(j);
double distance = distances[(int) coordinate.x][(int) coordinate.y];
if (distance > max) {
max = distance;
}
}
maxDistances[i] = max;
}
}

// 统计以不同距离为半径的同心圆内包含的像素数量
int[][] nums = new int[256][AnnularColorLayoutHistogram.N];
for (int i = 0; i <= 255; i++) {
for (int j = 1; j <= AnnularColorLayoutHistogram.N; j++) {
double minDis = maxDistances[i] * (j - 1) / AnnularColorLayoutHistogram.N;
double maxDis = maxDistances[i] * j / AnnularColorLayoutHistogram.N;
// 第一个同心圆的取值范围必须为[0, maxDis * j / n]
// 必须包含0，因为有可能存在像素点和质心重叠的情况
if (j == 1) {
minDis = -1;
}
List<Coordinate> list = groupedPixels.get(i);
int num = 0;
if (list == null)
continue;
for (int k = 0; k < list.size(); k++) {
Coordinate coordinate = list.get(k);
double dis = distances[(int) coordinate.x][(int) coordinate.y];
if (dis > minDis && dis <= maxDis) {
num++;
}
}
nums[i][j - 1] = num;
}
}
return nums;
}

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 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 buffImg = null;
buffImg = new BufferedImage(width, height, imageType);
buffImg.getGraphics().drawImage(srcImg.getScaledInstance(width, height, Image.SCALE_SMOOTH), 0, 0, null);
return buffImg;
}
}``````

### VenyoWang

VenyoWang
2016/07/06
1K
1
opencv 直方图匹配 图片颜色迁移

2018/08/25
15
0
9- OpenCV+TensorFlow 入门人工智能图像处理-8- OpenCV+TensorFlow 入门人工智能图像处理-图像修复

2018/05/08
0
0
Metal图像处理——直方图均衡化

2018/08/31
0
0

Tony沈哲
2017/05/22
0
0

18分钟前
4
0
Java Timer的用法

Timer timer = new Timer(); timer.schedule(new TimerTask() { public void run() { System.out.println("11232"); } }, 200000 , 1000); public void schedule(TimerTask task, long delay......

22分钟前
4
0

Bing309
30分钟前
3
0

34分钟前
3
0

34分钟前
3
0