/** * Recursive function query function. */ private void query(LimitedPriorityNodeList queue, NodeStack i_nodes, BinaryHierarchicalNode node, LongDescripter768 feature) { //近傍ノードをスタックに追加 int sp = i_nodes.getLength(); int num_of_min = nearest(node, i_nodes, queue, feature); //先頭からnum_of_min個の最小ノードについて再帰探索 for (int i = 0; i < num_of_min; i++) { BinaryHierarchicalNode n = i_nodes.getItem(sp + i).node; if (n.is_leaf) { this.append(n); } else { this.query(queue, i_nodes, n, feature); } } //好成績な近傍ノード1つを取り出して探索する。 NodeStack.Item item = this.mlist.popSmallest(); if (item != null) { BinaryHierarchicalNode n = item.node; if (n.is_leaf) { this.append(n); } else { this.query(queue, i_nodes, n, feature); } } return; }
public Keyframe(int width, int height, FreakMatchPointSetStack i_binaryFeatureStore) { this.mWidth = width; this.mHeight = height; this.mStore = i_binaryFeatureStore; BinaryHierarchicalClusterBuilder bhi = new BinaryHierarchicalClusterBuilder(i_binaryFeatureStore.getLength(), 128, 8, 16); this.mIndex = bhi.build(this.mStore); }
/** * Get a queue of all the children nodes sorted by distance from node center. */ private static int nearest(BinaryHierarchicalNode i_node, NodeStack nodes, LimitedPriorityNodeList queue, LongDescripter768 feature) { int mind = int.MaxValue; int sp = nodes.getLength(); BinaryHierarchicalNode[] children = i_node.children; int num_of_children = children.Length; //最小値の探索 for (int i = 0; i < num_of_children; i++) { NodeStack.Item item = nodes.prePush(); if (item == null) { //ワークエリアを使い切った。 return(0); } int d = children[i].center.descripter.hammingDistance(feature); item.node = children[i]; item.distance = d; if (d < mind) { mind = d; } } int num_of_min = 0; //最小値以外をキューに追記 for (int i = 0; i < num_of_children; i++) { NodeStack.Item item = nodes.getItem(sp + i); if (item.distance == mind) { //最小値は先頭に移動 nodes.swap(sp + num_of_min, sp + i); num_of_min++; } else { //最小値以外はキューに追加 queue.push(item); } } //最小値の数は(min_add_idx-s_idx) return(num_of_min); }
/** * Query the tree for a reverse index. */ public int query(BinaryHierarchicalNode i_node, LongDescripter768 feature) { this._num_of_result = 0; this.mlist.reset(); NodeStack nodes = this._node_stack; nodes.clear(); if (i_node.is_leaf) { this.append(i_node); } else { this.query(this.mlist, nodes, i_node, feature); } return((int)this._num_of_result); }
private void append(BinaryHierarchicalNode i_node) { //assert i_node.is_leaf==true; //末端なら結果配列へ値を追加 int p = this._num_of_result; int l = i_node.reserv_index.Length; // if (l + p > this._result.Length) { l = this._result.Length - this._num_of_result; } for (int i = 0; i < l; i++) { this._result[p + i] = i_node.reserv_index[i]; } this._num_of_result += l; return; }
/** * Match two feature stores with an index on features2. * * @return Number of matches */ override public int match(FreakFeaturePointStack i_query, Keyframe i_key_frame, FeaturePairStack i_maches) { //indexが無いときはベースクラスを使う。 BinaryHierarchicalNode index2 = i_key_frame.getIndex(); if (index2 == null) { return(base.match(i_query, i_key_frame, i_maches)); } FreakMatchPointSetStack ref_ = i_key_frame.getFeaturePointSet(); if (i_query.getLength() * ref_.getLength() == 0) { return(0); } FreakFeaturePoint[] query_buf = i_query.getArray(); int q_len = i_query.getLength(); for (int i = 0; i < q_len; i++) { int first_best = int.MaxValue; // std::numeric_limits<unsigned int>::max(); int second_best = int.MaxValue; // std::numeric_limits<unsigned int>::max(); FreakMatchPointSetStack.Item best_index = null; // std::numeric_limits<int>::max(); // Perform an indexed nearest neighbor lookup FreakFeaturePoint fptr1 = query_buf[i]; int num_of_fp = this._selector.query(index2, fptr1.descripter); // Search for 1st and 2nd best match FreakMatchPointSetStack.Item[] v = this._selector._result; for (int j = 0; j < num_of_fp; j++) { FreakFeaturePoint fptr2 = v[j]; // Both points should be a MINIMA or MAXIMA if (fptr1.maxima != fptr2.maxima) { continue; } int d = fptr1.descripter.hammingDistance(fptr2.descripter); if (d < first_best) { second_best = first_best; first_best = d; best_index = v[j]; } else if (d < second_best) { second_best = d; } } // Check if FIRST_BEST has been set if (first_best != int.MaxValue) { // If there isn't a SECOND_BEST, then always choose the FIRST_BEST. // Otherwise, do a ratio test. if (second_best == int.MaxValue) { FeaturePairStack.Item t = i_maches.prePush(); t.query = fptr1; t.ref_ = best_index; } else { // Ratio test double r = (double)first_best / (double)second_best; if (r < mThreshold) { // mMatches.push_back(match_t((int)i, best_index)); FeaturePairStack.Item t = i_maches.prePush(); t.query = fptr1; t.ref_ = best_index; } } } } return(i_maches.getLength()); }