public static List<GPoint> lookupAll(
      ImageBinary image, int x1, int y1, int x2, int y2, ImageBinary template, float m) {
    List<GPoint> list = new ArrayList<>();

    for (int x = x1; x <= x2 - template.getWidth() + 1; x++) {
      for (int y = y1; y <= y2 - template.getHeight() + 1; y++) {
        GPoint g = lookup(image, template, x, y, m);
        if (g != null) list.add(g);
      }
    }

    return list;
  }
  public static double gammaMin(ImageBinary image, ImageBinary template, int x, int y) {
    List<ImageBinaryChannel> ci = image.getChannels();
    List<ImageBinaryChannel> ct = template.getChannels();

    int ii = Math.min(ci.size(), ct.size());

    double g = Double.MAX_VALUE;

    for (int i = 0; i < ii; i++) {
      ImageBinaryChannel cct = ct.get(i);
      ImageBinaryChannel cci = ci.get(i);

      if (!cct.type.equals(cci.type)) throw new WrongChannelType();

      g = Math.min(g, gamma(cci, cct, x, y));
    }

    return g;
  }
  public static GPoint lookup(ImageBinary image, ImageBinary template, int x, int y, float m) {
    List<ImageBinaryChannel> ci = image.getChannels();
    List<ImageBinaryChannel> ct = template.getChannels();

    int ii = Math.min(ci.size(), ct.size());

    double g = Double.MAX_VALUE;

    for (int i = 0; i < ii; i++) {
      ImageBinaryChannel cct = ct.get(i);
      ImageBinaryChannel cci = ci.get(i);

      if (!cct.type.equals(cci.type)) throw new WrongChannelType();

      double gg = gamma(cci, cct, x, y);

      if (gg < m) return null;

      g = Math.min(g, gg);
    }

    return new GPoint(x, y, g);
  }
 public static List<GPoint> lookupAll(ImageBinary image, ImageBinary template, float m) {
   return lookupAll(image, 0, 0, image.getWidth() - 1, image.getHeight() - 1, template, m);
 }