public WrapFusedKltTracker(
      InterestPointDetector<I> detector, PyramidKltForCombined<I, D> tracker, Class<I> imageType) {
    this.detector = detector;
    this.tracker = tracker;

    derivType = GImageDerivativeOps.getDerivativeType(imageType);

    gradient = FactoryDerivative.sobel(imageType, derivType);

    int pyramidScaling[] = tracker.pyramidScaling;

    pyramid = FactoryPyramid.discreteGaussian(pyramidScaling, -1, 2, true, imageType);
  }
  /**
   * Any arbitrary implementation of InterestPointDetector, OrientationImage, DescribeRegionPoint
   * can be combined into DetectDescribePoint. The syntax is more complex, but the end result is
   * more flexible. This should only be done if there isn't a pre-made DetectDescribePoint.
   */
  public static <T extends ImageSingleBand, D extends TupleDesc>
      DetectDescribePoint<T, D> createFromComponents(Class<T> imageType) {
    // create a corner detector
    Class derivType = GImageDerivativeOps.getDerivativeType(imageType);
    GeneralFeatureDetector corner =
        FactoryDetectPoint.createShiTomasi(new ConfigGeneralDetector(1000, 5, 1), false, derivType);
    InterestPointDetector detector =
        FactoryInterestPoint.wrapPoint(corner, 1, imageType, derivType);

    // describe points using BRIEF
    DescribeRegionPoint describe =
        FactoryDescribeRegionPoint.brief(new ConfigBrief(true), imageType);

    // Combine together.
    // NOTE: orientation will not be estimated
    return FactoryDetectDescribe.fuseTogether(detector, null, describe);
  }
  public static void main(String args[]) {
    Class imageType = ImageFloat32.class;
    Class derivType = GImageDerivativeOps.getDerivativeType(imageType);

    VisualizeAssociationMatchesApp app = new VisualizeAssociationMatchesApp(imageType, derivType);

    List<PathLabel> inputs = new ArrayList<PathLabel>();

    inputs.add(
        new PathLabel(
            "Cave",
            "../data/evaluation/stitch/cave_01.jpg",
            "../data/evaluation/stitch/cave_02.jpg"));
    inputs.add(
        new PathLabel(
            "Kayak",
            "../data/evaluation/stitch/kayak_02.jpg",
            "../data/evaluation/stitch/kayak_03.jpg"));
    inputs.add(
        new PathLabel(
            "Forest",
            "../data/evaluation/scale/rainforest_01.jpg",
            "../data/evaluation/scale/rainforest_02.jpg"));
    inputs.add(
        new PathLabel(
            "Building",
            "../data/evaluation/stitch/apartment_building_01.jpg",
            "../data/evaluation/stitch/apartment_building_02.jpg"));
    inputs.add(
        new PathLabel(
            "Trees Rotate",
            "../data/evaluation/stitch/trees_rotate_01.jpg",
            "../data/evaluation/stitch/trees_rotate_03.jpg"));

    app.setPreferredSize(new Dimension(1000, 500));
    app.setSize(1000, 500);
    app.setInputList(inputs);

    // wait for it to process one image so that the size isn't all screwed up
    while (!app.getHasProcessedImage()) {
      Thread.yield();
    }

    ShowImages.showWindow(app, "Associated Features");
  }