package com.alibaba.simpleimage.analyze.search.tree; import java.io.Serializable; import java.util.ArrayList; import java.util.LinkedList; import java.util.List; import com.alibaba.simpleimage.analyze.search.cluster.ClusterBuilder; import com.alibaba.simpleimage.analyze.search.cluster.Clusterable; import com.alibaba.simpleimage.analyze.search.cluster.impl.Cluster; import com.alibaba.simpleimage.analyze.search.util.TreeUtils; public class KMeansTree implements VocabularyTree, Serializable { private static final long serialVersionUID = 1L; public static int idCount = 0; private int branchFactor = 10; private int maxHeight = 6; private int treeHeight = 0; private int numWords = 0; // The total number of descriptors added to the tree for word // creation private KMeansTreeNode rootNode; // private List<KMeansTreeNode> mBreadthWiseList;//A list of all of the nodes from a depth wise search /** * This creates a new tree from the items * * @param items * @param branchFactor * @param leafNodeCapacity */ public KMeansTree(List<Clusterable> items, int branchFactor, int height, ClusterBuilder clusterer){ this.branchFactor = branchFactor; maxHeight = height; rootNode = new KMeansTreeNode(Cluster.getMeanValue(items), items, this.branchFactor, maxHeight, 0, clusterer); } public int getBranchFactor() { return this.branchFactor; } public int getNumWords() { return this.numWords; } public List<KMeansTreeNode> getBreadthWiseList() { List<KMeansTreeNode> nodes = new ArrayList<KMeansTreeNode>(rootNode.getNumSubItems() + 1); List<KMeansTreeNode> nodesLeft = new LinkedList<KMeansTreeNode>(); nodesLeft.add(rootNode); KMeansTreeNode node = nodesLeft.remove(0); while (node != null) { // TODO: Remove (but why?) nodes.add(node); if (!node.isLeafNode()) nodesLeft.addAll(node.getSubNodes()); if (nodesLeft.size() > 0) node = nodesLeft.remove(0); else node = null; } return nodes; } public List<KMeansTreeNode> getLeafsList() { List<KMeansTreeNode> nodes = new ArrayList<KMeansTreeNode>(rootNode.getNumSubItems() + 1); List<KMeansTreeNode> nodesLeft = new LinkedList<KMeansTreeNode>(); nodesLeft.add(rootNode); KMeansTreeNode node = nodesLeft.remove(0); while (node != null) { if (node.isLeafNode()) { nodes.add(node); } else { nodesLeft.addAll(node.getSubNodes()); } if (nodesLeft.size() > 0) { node = nodesLeft.remove(0); } else { node = null; } } return nodes; } public List<Integer> getVisualWords(List<? extends Clusterable> imagePoints) { List<Integer> visual_word_list = new ArrayList<Integer>(); for (Clusterable value : imagePoints) { visual_word_list.add(getVisualWord(value)); } return visual_word_list; } public int getVisualWord(Clusterable point) { numWords += 1; return rootNode.getValueId(point); } /** * Will return the current word in a depth wise search on the tree */ public List<Float> getCurrentWords() { return TreeUtils.getCurrentWord(rootNode, rootNode.getNumSubItems()); } public void reset() { numWords = 0; rootNode.reset(); } public int getTreeHeight() { return treeHeight; } public KMeansTreeNode getRootNode() { return rootNode; } }