public bool extractMatches(FeaturePairStack i_matche_resule, int refWidth, int refHeight) { // Extract the data from the features // hough.vote((float*)&query[0], (float*)&ref[0], (int)matches.size()); int size = i_matche_resule.getLength(); if (size == 0) { return(false); } //ワークエリア if (this._mSubBinLocations.Length < size) { this._mSubBinLocations = SubBinLocation.createArray(size + 10); } //FindHoughSimilarity int max_dim = refWidth > refHeight ? refWidth : refHeight;//math_utils.max2(mRefImageWidth, mRefImageHeight); if (!this.autoAdjustXYNumBins(max_dim, i_matche_resule)) { return(false); } this.votemap.reset(); int num_of_subbin = this.vote(i_matche_resule, refWidth / 2, refHeight / 2, this._mSubBinLocations); int max_hough_index = this.votemap.findMax(); if (max_hough_index < 0) { return(false); } this.FindHoughMatches(i_matche_resule, max_hough_index, kHoughBinDelta, this._mSubBinLocations, num_of_subbin); return(true); }
public static SubBinLocation[] createArray(int i_length) { SubBinLocation[] r = new SubBinLocation[i_length]; for (int i = 0; i < i_length; i++) { r[i] = new SubBinLocation(); } return(r); }
private int vote(FeaturePairStack i_point_pair, int i_center_x, int i_center_y, SubBinLocation[] i_sub_bin_locations) { int size = i_point_pair.getLength(); int num_features_that_cast_vote = 0; for (int i = 0; i < size; i++) { //mapCorrespondence(r,i_point_pair.getItem(i),i_center_x,i_center_y); double rx, ry, rangle, rscale; { FreakFeaturePoint ins = i_point_pair.getItem(i).query; FreakFeaturePoint ref_ = i_point_pair.getItem(i).ref_; //angle rangle = ins.angle - ref_.angle; // Map angle to (-pi,pi] if (rangle <= -PI) { rangle += (2 * PI); } else if (rangle > PI) { rangle -= (2 * PI); } double scale = SafeDivision(ins.scale, ref_.scale); double c = (scale * Math.Cos(rangle)); double s = (scale * Math.Sin(rangle)); //scale rscale = (double)(Math.Log(scale) * this.mScaleOneOverLogK); //x,y rx = c * i_center_x - s * i_center_y + (ins.x - (c * ref_.x - s * ref_.y)); ry = s * i_center_x + c * i_center_y + (ins.y - (s * ref_.x + c * ref_.y)); // Check that the vote is within range if (rx < mMinX || rx >= mMaxX || ry < mMinY || ry >= mMaxY || rangle <= -PI || rangle > PI || rscale < mMinScale || rscale >= mMaxScale) { continue; } } // Compute the bin location SubBinLocation sub_bin = i_sub_bin_locations[num_features_that_cast_vote]; mapVoteToBin(sub_bin, rx, ry, rangle, rscale); int binX = (int)Math.Floor(sub_bin.x - 0.5f); int binY = (int)Math.Floor(sub_bin.y - 0.5f); int binScale = (int)Math.Floor(sub_bin.scale - 0.5f); int binAngle = ((int)Math.Floor(sub_bin.angle - 0.5f) + mNumAngleBins) % mNumAngleBins; // Check that we can voting to all 16 bin locations if (binX < 0 || (binX + 1) >= mNumXBins || binY < 0 || (binY + 1) >= mNumYBins || binScale < 0 || (binScale + 1) >= mNumScaleBins) { continue; } sub_bin.index = i; num_features_that_cast_vote++; this.votemap.vote16(binX, binY, binAngle, binScale, 1); } return(num_features_that_cast_vote); }
/** * Get only the matches that are consistent based on the hough votes. */ private void FindHoughMatches(FeaturePairStack in_matches, int binIndex, double binDelta, SubBinLocation[] i_sub_bin, int i_num_of_sbin) { /** * Get the bins locations from an index. */ double ref_x, ref_y, ref_angle, ref_scale; { //ハッシュ値から元の値を復帰 int binX = binIndex & 0x3f; int binY = (binIndex >> 7) & 0x3f; int binAngle = (binIndex >> 14) & 0x3f; int binScale = (binIndex >> 21) & 0x3f; ref_x = binX + 0.5; ref_y = binY + 0.5; ref_angle = binAngle + 0.5; ref_scale = binScale + 0.5; } // int pos = 0; for (int i = 0; i < i_num_of_sbin; i++) { SubBinLocation ins = i_sub_bin[i]; //getBinDistance double d; //x d = Math.Abs(ins.x - ref_x); if (d >= binDelta) { continue; } //y d = Math.Abs(ins.y - ref_y); if (d >= binDelta) { continue; } //scale d = Math.Abs(ins.scale - ref_scale); if (d >= binDelta) { continue; } // Angle double d1 = Math.Abs(ins.angle - ref_angle); double d2 = (double)this.mNumAngleBins - d1; d = d1 < d2 ? d1 : d2; if (d >= binDelta) { continue; } //idxは昇順のはずだから詰める。 int idx = ins.index; in_matches.swap(idx, pos); pos++; } in_matches.setLength(pos); return; }