/** Checks to see if the two ways of specifying interpolation work */
  @Test
  public void scale_InterpTypeStyle() {
    ImageFloat32 input = new ImageFloat32(width, height);
    ImageFloat32 output = new ImageFloat32(width, height);

    GImageMiscOps.fillUniform(input, rand, 0, 100);

    DistortImageOps.scale(input, output, TypeInterpolate.BILINEAR);

    InterpolatePixel<ImageFloat32> interp = FactoryInterpolation.bilinearPixel(input);
    interp.setImage(input);

    float scaleX = (float) input.width / (float) output.width;
    float scaleY = (float) input.height / (float) output.height;

    if (input.getTypeInfo().isInteger()) {
      for (int i = 0; i < output.height; i++) {
        for (int j = 0; j < output.width; j++) {
          float val = interp.get(j * scaleX, i * scaleY);
          assertEquals((int) val, output.get(j, i), 1e-4);
        }
      }
    } else {
      for (int i = 0; i < output.height; i++) {
        for (int j = 0; j < output.width; j++) {
          float val = interp.get(j * scaleX, i * scaleY);
          assertEquals(val, output.get(j, i), 1e-4);
        }
      }
    }
  }
  public void checkInner(ImageFloat32 image, int c_x, int c_y, int w, int h) {
    ImplDescribePointPixelRegionNCC_F32 alg = new ImplDescribePointPixelRegionNCC_F32(w, h);

    NccFeature desc = new NccFeature(alg.getDescriptorLength());
    alg.setImage(image);
    assertTrue(alg.isInBounds(c_x, c_y));
    alg.process(c_x, c_y, desc);

    int y0 = c_y - h / 2;
    int x0 = c_x - w / 2;
    double mean = 0;
    for (int y = y0; y < y0 + h; y++) {
      for (int x = x0; x < x0 + w; x++) {
        mean += image.get(x, y);
      }
    }
    mean /= w * h;
    double variance = 0;
    for (int y = y0; y < y0 + h; y++) {
      for (int x = x0; x < x0 + w; x++) {
        double a = image.get(x, y) - mean;
        variance += a * a;
      }
    }
    variance /= w * h;
    assertEquals(desc.mean, mean, 1e-8);
    assertEquals(desc.sigma, Math.sqrt(variance), 1e-8);

    int index = 0;
    for (int y = y0; y < y0 + h; y++) {
      for (int x = x0; x < x0 + w; x++, index++) {
        assertEquals(image.get(x, y) - mean, desc.value[index], 1e-4);
      }
    }
  }
  @Test
  public void checkIntensity() {
    ImageUInt8 input = new ImageUInt8(40, 50);
    ImageFloat32 intensity = new ImageFloat32(input.width, input.height);

    int[] offsets = DiscretizedCircle.imageOffsets(3, input.stride);
    createCircle(4, 5, offsets, minContinuous, detectDifference + 1, input);
    createCircle(12, 20, offsets, minContinuous, detectDifference + 10, input);

    alg.process(input, intensity);

    assertTrue(intensity.get(4, 5) < intensity.get(12, 20));
  }
  private void checUpSample(int w, int h) {
    ImageFloat32 input = new ImageFloat32(w, h);
    ImageFloat32 output = new ImageFloat32(w * 2, h * 2);

    GImageMiscOps.fillUniform(input, rand, 0, 100);

    SiftImageScaleSpace.upSample(input, output);

    for (int i = 0; i < output.height; i++) {
      for (int j = 0; j < output.width; j++) {
        assertTrue(input.get(j / 2, i / 2) == output.get(j, i));
      }
    }
  }
  /**
   * Computes the mean squared error (MSE) between the two images.
   *
   * @param imgA first image. Not modified.
   * @param imgB second image. Not modified.
   * @return error between the two images.
   */
  public static double computeMeanSquaredError(ImageFloat32 imgA, ImageFloat32 imgB) {
    final int h = imgA.getHeight();
    final int w = imgA.getWidth();

    double total = 0;

    for (int y = 0; y < h; y++) {
      for (int x = 0; x < w; x++) {
        double difference = imgA.get(x, y) - imgB.get(x, y);
        total += difference * difference;
      }
    }

    return total / (w * h);
  }
示例#6
0
  public static BufferedImage standard(ImageSingleBand<?> src, BufferedImage dst) {
    if (src.getDataType().isInteger()) {
      ImageInteger srcInt = (ImageInteger) src;

      if (src.getDataType().isSigned()) {
        double max = GImageStatistics.maxAbs(srcInt);
        return colorizeSign(srcInt, dst, (int) max);
      } else {
        if (src.getDataType().getNumBits() == 8) {
          dst = ConvertBufferedImage.convertTo((ImageUInt8) src, dst);
        } else {
          double max = GImageStatistics.maxAbs(srcInt);
          dst = grayUnsigned(srcInt, dst, (int) max);
        }
      }
    } else if (ImageFloat32.class.isAssignableFrom(src.getClass())) {
      ImageFloat32 img = (ImageFloat32) src;
      float max = ImageStatistics.maxAbs(img);

      boolean hasNegative = false;
      for (int i = 0; i < img.getHeight(); i++) {
        for (int j = 0; j < img.getWidth(); j++) {
          if (img.get(j, i) < 0) {
            hasNegative = true;
            break;
          }
        }
      }

      if (hasNegative) return colorizeSign(img, dst, (int) max);
      else return grayMagnitude((ImageFloat32) src, dst, max);
    }

    return dst;
  }
  @Test
  public void scaleSanityCheck() {
    ImageFloat32 input = new ImageFloat32(width, height);
    ImageFloat32 output = new ImageFloat32(width / 2, height / 2);

    GImageMiscOps.fillUniform(input, rand, 0, 100);

    DistortImageOps.scale(input, output, TypeInterpolate.BILINEAR);

    double error = 0;
    for (int y = 0; y < output.height; y++) {
      for (int x = 0; x < output.width; x++) {
        double e = input.get(x * 2, y * 2) - output.get(x, y);
        error += Math.abs(e);
      }
    }
    assertTrue(error / (output.width * output.height) < 0.1);
  }
  private void shiftCopy(int offX, int offY, ImageFloat32 src, ImageFloat32 dst) {
    for (int y = 0; y < src.height; y++) {
      for (int x = 0; x < src.width; x++) {
        int xx = x + offX;
        int yy = y + offY;

        if (xx >= 0 && xx < src.width && yy >= 0 && yy < src.height) {
          dst.set(xx, yy, src.get(x, y));
        }
      }
    }
  }
  /** Very simple test for rotation accuracy. */
  @Test
  public void rotate_SanityCheck() {
    ImageFloat32 input = new ImageFloat32(width, height);
    ImageFloat32 output = new ImageFloat32(height, width);

    GImageMiscOps.fillUniform(input, rand, 0, 100);

    DistortImageOps.rotate(input, output, TypeInterpolate.BILINEAR, (float) Math.PI / 2f);

    double error = 0;
    // the outside pixels are ignored because numerical round off can cause those to be skipped
    for (int y = 1; y < input.height - 1; y++) {
      for (int x = 1; x < input.width - 1; x++) {
        int xx = output.width - y;
        int yy = x;

        double e = input.get(x, y) - output.get(xx, yy);
        error += Math.abs(e);
      }
    }
    assertTrue(error / (width * height) < 0.1);
  }
示例#10
0
  /**
   * Checks to see if the BufferedImage has the same intensity values as the ImageUInt8
   *
   * @param imgA BufferedImage
   * @param imgB ImageUInt8
   */
  public static void checkEquals(BufferedImage imgA, ImageFloat32 imgB, float tol) {

    if (imgA.getRaster() instanceof ByteInterleavedRaster
        && imgA.getType() != BufferedImage.TYPE_BYTE_INDEXED) {
      ByteInterleavedRaster raster = (ByteInterleavedRaster) imgA.getRaster();

      if (raster.getNumBands() == 1) {
        int strideA = raster.getScanlineStride();
        int offsetA = raster.getDataOffset(0) - raster.getNumBands() + 1;

        // handle a special case where the RGB conversion is screwed
        for (int i = 0; i < imgA.getHeight(); i++) {
          for (int j = 0; j < imgA.getWidth(); j++) {
            float valB = imgB.get(j, i);
            int valA = raster.getDataStorage()[offsetA + i * strideA + j];
            valA &= 0xFF;

            if (Math.abs(valA - valB) > tol)
              throw new RuntimeException("Images are not equal: A = " + valA + " B = " + valB);
          }
        }
        return;
      }
    }

    for (int y = 0; y < imgA.getHeight(); y++) {
      for (int x = 0; x < imgA.getWidth(); x++) {
        int rgb = imgA.getRGB(x, y);

        float gray = (((rgb >>> 16) & 0xFF) + ((rgb >>> 8) & 0xFF) + (rgb & 0xFF)) / 3.0f;
        float grayB = imgB.get(x, y);

        if (Math.abs(gray - grayB) > tol) {
          throw new RuntimeException("images are not equal: A = " + gray + " B = " + grayB);
        }
      }
    }
  }
示例#11
0
  private static BufferedImage grayMagnitude(
      ImageFloat32 src, BufferedImage dst, float maxAbsValue) {
    for (int y = 0; y < src.height; y++) {
      for (int x = 0; x < src.width; x++) {
        float v = Math.abs(src.get(x, y));

        int rgb = (int) (255 * v / maxAbsValue);

        dst.setRGB(x, y, rgb << 16 | rgb << 8 | rgb);
      }
    }

    return dst;
  }
  @Test
  public void checkRender() {
    // Easier to make up a plane in this direction
    Se3_F64 cameraToPlane = new Se3_F64();
    ConvertRotation3D_F64.eulerToMatrix(
        EulerType.XYZ, UtilAngle.degreeToRadian(0), 0, 0, cameraToPlane.getR());
    cameraToPlane.getT().set(0, -5, 0);

    Se3_F64 planeToCamera = cameraToPlane.invert(null);

    CreateSyntheticOverheadViewMS<ImageFloat32> alg =
        new CreateSyntheticOverheadViewMS<ImageFloat32>(
            TypeInterpolate.BILINEAR, 3, ImageFloat32.class);

    alg.configure(param, planeToCamera, centerX, centerY, cellSize, overheadW, overheadH);

    MultiSpectral<ImageFloat32> input =
        new MultiSpectral<ImageFloat32>(ImageFloat32.class, width, height, 3);
    for (int i = 0; i < 3; i++) ImageMiscOps.fill(input.getBand(i), 10 + i);

    MultiSpectral<ImageFloat32> output =
        new MultiSpectral<ImageFloat32>(ImageFloat32.class, overheadW, overheadH, 3);

    alg.process(input, output);

    for (int i = 0; i < 3; i++) {
      ImageFloat32 o = output.getBand(i);

      // check parts that shouldn't be in view
      assertEquals(0, o.get(0, 300), 1e-8);
      assertEquals(0, o.get(5, 0), 1e-8);
      assertEquals(0, o.get(5, 599), 1e-8);

      // check areas that should be in view
      assertEquals(10 + i, o.get(499, 300), 1e-8);
    }
  }
  public void checkInner(ImageFloat32 image, int c_x, int c_y, int w, int h) {
    ImplDescribePointPixelRegion_F32 alg = new ImplDescribePointPixelRegion_F32(w, h);

    TupleDesc_F32 desc = new TupleDesc_F32(alg.getDescriptorLength());
    alg.setImage(image);
    alg.process(c_x, c_y, desc);

    int index = 0;
    int y0 = c_y - h / 2;
    int x0 = c_x - w / 2;
    for (int y = y0; y < y0 + h; y++) {
      for (int x = x0; x < x0 + w; x++, index++) {
        assertEquals(image.get(x, y), desc.value[index], 1e-4);
      }
    }
  }
示例#14
0
  public static BufferedImage graySign(ImageFloat32 src, BufferedImage dst, float maxAbsValue) {
    dst = checkInputs(src, dst);

    if (maxAbsValue < 0) maxAbsValue = ImageStatistics.maxAbs(src);

    for (int y = 0; y < src.height; y++) {
      for (int x = 0; x < src.width; x++) {
        float v = src.get(x, y);

        int rgb = 127 + (int) (127 * v / maxAbsValue);

        dst.setRGB(x, y, rgb << 16 | rgb << 8 | rgb);
      }
    }

    return dst;
  }
示例#15
0
  private static BufferedImage colorizeSign(
      ImageFloat32 src, BufferedImage dst, float maxAbsValue) {
    for (int y = 0; y < src.height; y++) {
      for (int x = 0; x < src.width; x++) {
        float v = src.get(x, y);

        int rgb;
        if (v > 0) {
          rgb = (int) (255 * v / maxAbsValue) << 16;
        } else {
          rgb = (int) (-255 * v / maxAbsValue) << 8;
        }
        dst.setRGB(x, y, rgb);
      }
    }

    return dst;
  }
  public static void process(ImageFloat32 input, ImageFloat32 output, int radius, float storage[]) {
    int w = 2 * radius + 1;
    if (storage == null) {
      storage = new float[w * w];
    } else if (storage.length < w * w) {
      throw new IllegalArgumentException("'storage' must be at least of length " + (w * w));
    }

    for (int y = 0; y < radius; y++) {
      int minI = y - radius;
      int maxI = y + radius + 1;
      if (minI < 0) minI = 0;
      if (maxI > input.height) maxI = input.height;

      for (int x = 0; x < input.width; x++) {
        int minJ = x - radius;
        int maxJ = x + radius + 1;

        // bound it ot be inside the image
        if (minJ < 0) minJ = 0;
        if (maxJ > input.width) maxJ = input.width;

        int index = 0;

        for (int i = minI; i < maxI; i++) {
          for (int j = minJ; j < maxJ; j++) {
            storage[index++] = input.get(j, i);
          }
        }

        // use quick select to avoid sorting the whole list
        float median = QuickSelectArray.select(storage, index / 2, index);
        output.set(x, y, median);
      }
    }

    for (int y = input.height - radius; y < input.height; y++) {
      int minI = y - radius;
      int maxI = y + radius + 1;
      if (minI < 0) minI = 0;
      if (maxI > input.height) maxI = input.height;

      for (int x = 0; x < input.width; x++) {
        int minJ = x - radius;
        int maxJ = x + radius + 1;

        // bound it ot be inside the image
        if (minJ < 0) minJ = 0;
        if (maxJ > input.width) maxJ = input.width;

        int index = 0;

        for (int i = minI; i < maxI; i++) {
          for (int j = minJ; j < maxJ; j++) {
            storage[index++] = input.get(j, i);
          }
        }

        // use quick select to avoid sorting the whole list
        float median = QuickSelectArray.select(storage, index / 2, index);
        output.set(x, y, median);
      }
    }

    for (int y = radius; y < input.height - radius; y++) {
      int minI = y - radius;
      int maxI = y + radius + 1;
      for (int x = 0; x < radius; x++) {
        int minJ = x - radius;
        int maxJ = x + radius + 1;

        // bound it ot be inside the image
        if (minJ < 0) minJ = 0;
        if (maxJ > input.width) maxJ = input.width;

        int index = 0;

        for (int i = minI; i < maxI; i++) {
          for (int j = minJ; j < maxJ; j++) {
            storage[index++] = input.get(j, i);
          }
        }

        // use quick select to avoid sorting the whole list
        float median = QuickSelectArray.select(storage, index / 2, index);
        output.set(x, y, median);
      }
    }

    for (int y = radius; y < input.height - radius; y++) {
      int minI = y - radius;
      int maxI = y + radius + 1;
      for (int x = input.width - radius; x < input.width; x++) {
        int minJ = x - radius;
        int maxJ = x + radius + 1;

        // bound it ot be inside the image
        if (minJ < 0) minJ = 0;
        if (maxJ > input.width) maxJ = input.width;

        int index = 0;

        for (int i = minI; i < maxI; i++) {
          for (int j = minJ; j < maxJ; j++) {
            storage[index++] = input.get(j, i);
          }
        }

        // use quick select to avoid sorting the whole list
        float median = QuickSelectArray.select(storage, index / 2, index);
        output.set(x, y, median);
      }
    }
  }