前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >环形颜色分布直方图

环形颜色分布直方图

作者头像
Venyo
发布2018-03-15 13:16:13
9200
发布2018-03-15 13:16:13
举报
文章被收录于专栏:Venyo 的专栏Venyo 的专栏
代码语言:javascript
复制
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>
 * http://wenku.baidu.com/link?url=bWfVkM-oyUn7cJuCnhICReeByt2XR-MUx07J-
 * 1pXvBz7UKzoe4iGmH4S-8j4MiuAXyzetBV7NEDwJC7BBjT8ecCpHvo7oSBNChO0gLJMhI7<br>
 * http://wenku.baidu.com/link?url=s13-4JCwPWfHsnv1EKXcScLNs06-NEN2gBG-
 * 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;
				list.add(coordinate);
				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 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;
	}
}
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档