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");
  }
  public IntensityFeatureScaleSpacePyramidApp(Class<T> imageType, Class<D> derivType) {
    super(1);
    this.imageType = imageType;

    addAlgorithm(
        0,
        "Hessian Det",
        new WrapperHessianBlobIntensity<T, D>(HessianBlobIntensity.Type.DETERMINANT, derivType));
    addAlgorithm(
        0,
        "Laplacian",
        new WrapperHessianBlobIntensity<T, D>(HessianBlobIntensity.Type.TRACE, derivType));
    addAlgorithm(
        0,
        "Harris",
        new WrapperGradientCornerIntensity<T, D>(
            FactoryIntensityPointAlg.harris(2, 0.4f, false, derivType)));
    addAlgorithm(
        0,
        "Shi Tomasi",
        new WrapperGradientCornerIntensity<T, D>(
            FactoryIntensityPointAlg.shiTomasi(2, false, derivType)));
    addAlgorithm(
        0,
        "FAST 12",
        new WrapperFastCornerIntensity<T, D>(FactoryIntensityPointAlg.fast12(5, 11, imageType)));
    addAlgorithm(0, "KitRos", new WrapperKitRosCornerIntensity<T, D>(derivType));
    addAlgorithm(
        0,
        "Median",
        new WrapperMedianCornerIntensity<T, D>(FactoryBlurFilter.median(imageType, 2), imageType));

    setMainGUI(gui);

    double scales[] = new double[25];
    for (int i = 0; i < scales.length; i++) {
      scales[i] = Math.exp(i * 0.15);
    }
    pyramid = new ScaleSpacePyramid<T>(imageType, scales);

    anyDerivative =
        GImageDerivativeOps.createDerivatives(imageType, FactoryImageGenerator.create(derivType));
  }