Package graphmatcher.helper

Source Code of graphmatcher.helper.TransformationEstimator

package graphmatcher.helper;

import graphmatcher.graph.Graph;

import java.awt.Point;
import java.awt.geom.AffineTransform;
import java.awt.geom.Point2D;
import java.util.Arrays;
import java.util.Random;
import java.util.Vector;

import org.apache.log4j.Level;
import org.apache.log4j.Logger;

import Jama.Matrix;

public class TransformationEstimator {
  private static Logger logger = Logger.getLogger(TransformationEstimator.class);

  static {
    logger.setLevel(Level.OFF);
  }

  public static EstimatedTransformationContainer lmsEstimator(Graph pattern, Graph template, int[] matching) {
    long timeStart = System.currentTimeMillis();
    Vector<Point> patternPoints = new Vector<Point>();
    Vector<Point> templatePoints = new Vector<Point>();
    for (int i = 0; i < matching.length; i++) {
      if (matching[i] == -1) {
        // nicht gematcht
        continue;
      }
      patternPoints.add(pattern.vertices()[i].toPoint());
      templatePoints.add(template.vertices()[matching[i]].toPoint());
    }

    int minPoints = Math.min(patternPoints.size(), templatePoints.size());
    if (minPoints < 4) {
      // logger.warn("zu wenig Knoten!");
      throw new IllegalArgumentException(
          "Zu wenig Knoten gematcht! Transformation kann nicht berechnet werden");
    }
    int MAX_ITER = 100;
    Vector<EstimatedTransformationContainer> bestAffineTransform = new Vector<EstimatedTransformationContainer>();
    EstimatedTransformationContainer dummyTap = new EstimatedTransformationContainer();
    bestAffineTransform.add(dummyTap);
    Point p1, p2, p3, q1, q2, q3;
    Random random = new Random();
    for (int iter = 0; iter < MAX_ITER; iter++) {
      int r1, r2, r3;
      if (minPoints > 10) {
        r1 = random.nextInt(patternPoints.size());
        r2 = random.nextInt(patternPoints.size());
        while (r2 == r1) {
          r2 = random.nextInt(patternPoints.size());
        }
        r3 = r2;
        while ((r3 == r2) || (r3 == r1)) {
          r3 = random.nextInt(patternPoints.size());
        }
      } else {
        Vector<Integer> vector = new Vector<Integer>();
        for (int i = 0; i < minPoints; i++) {
          vector.add(i);
        }
        r1 = vector.remove(random.nextInt(vector.size()));
        r2 = vector.remove(random.nextInt(vector.size()));
        r3 = vector.remove(random.nextInt(vector.size()));
      }
      p1 = patternPoints.get(r1);
      p2 = patternPoints.get(r2);
      p3 = patternPoints.get(r3);

      q1 = templatePoints.get(r1);
      q2 = templatePoints.get(r2);
      q3 = templatePoints.get(r3);

      double[][] array1 = { { p1.x, p1.y, 1 }, { p2.x, p2.y, 1 }, { p3.x, p3.y, 1 } };
      Matrix matrix = new Matrix(array1);

      try {
        double[][] vector1_ = { { q1.x }, { q2.x }, { q3.x } };
        Matrix vector1 = new Matrix(vector1_);

        Matrix result1 = matrix.solve(vector1);
        double[][] zeile1 = result1.getArray();

        double[][] vector2_ = { { q1.y }, { q2.y }, { q3.y } };
        Matrix vector2 = new Matrix(vector2_);

        Matrix result2 = matrix.solve(vector2);
        double[][] zeile2 = result2.getArray();

        double a11 = zeile1[0][0];
        double a12 = zeile1[1][0];
        double a13 = zeile1[2][0];

        double a21 = zeile2[0][0];
        double a22 = zeile2[1][0];
        double a23 = zeile2[2][0];
        AffineTransform affineTransform = new AffineTransform(a11, a21, a12, a22, a13, a23);
        int medianMatchingEdgeLength = getMedianOfMatchingEdges(patternPoints, templatePoints,
            affineTransform);

        for (int i = 0; i < 2; i++) {
          if (medianMatchingEdgeLength < bestAffineTransform.get(i).medianMatchingEdge) {
            EstimatedTransformationContainer container = new EstimatedTransformationContainer();
            container.affineTransform = affineTransform;
            container.r1 = r1;
            container.r2 = r2;
            container.r3 = r3;
            container.medianMatchingEdge = medianMatchingEdgeLength;
            bestAffineTransform.add(i, container);
            if (bestAffineTransform.size() > 2) {
              bestAffineTransform.remove(2);
            }
            break;
          }
        }
      } catch (Exception e) {
      }
    }
    int size = bestAffineTransform.size();
    if (size < 2) {
      logger.warn("(TransformationEstimator) Vector kritisch: " + size);
    }
    // logger.info("0:" + bestAffineTransform.get(0).toString());
    // logger.info("1:" + bestAffineTransform.get(1).toString());
    EstimatedTransformationContainer result = bestAffineTransform.get(0);
    result.time = System.currentTimeMillis() - timeStart;
    return result;
  }

  /**
   * Berechnet die L�nge aller Matchingkanten. Gibt die L�nge der mittleren
   * zur�ck.
   *
   * @param patternPoints
   * @param templatePoints
   * @param affineTransform
   * @return
   */
  private static int getMedianOfMatchingEdges(Vector<Point> patternPoints, Vector<Point> templatePoints,
      AffineTransform affineTransform) {
    int[] lengthMatchingEdges = new int[patternPoints.size()];
    for (int i = 0; i < patternPoints.size(); i++) {
      Point patternPoint = patternPoints.get(i);
      Point templatePoint = templatePoints.get(i);
      Point transformedPatternPoint;
      Point2D p = affineTransform.transform(patternPoint, null);
      transformedPatternPoint = new Point((int) p.getX(), (int) p.getY());
      double distance = DistanceHelper.getDistance(templatePoint, transformedPatternPoint);
      lengthMatchingEdges[i] = (int) distance;
    }
    Arrays.sort(lengthMatchingEdges);
    return lengthMatchingEdges[lengthMatchingEdges.length / 2];
  }
}
TOP

Related Classes of graphmatcher.helper.TransformationEstimator

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.