I have two photos, one zoomed in and the second a large, wide angle photo. Consider the first image a crop of the second(though it is not). I select a single pixel from each photo that represents the same thing in both pictures (say a man's nose). I overlay the first picture, with some transparency, on top of the second picture aligning the two selected pixels?
Now I want to scale the second image until the first image essentially disappears because the scale of the second image matches the scale of the first.
I am using OpenImaj and have successfully accomplished this using MBFImage.overlayInPlace(). The problem I have is that when I use ResizeProcessor to scale the second image, I get an "OutOfMemoryError: Java Heap Space" if I have to scale the second image too much ( >5x ).
I have bumped up the -Xmx to 12G using JDK 12 64bit. I have tried the ResizeProcessor, BilinearInterpolation and BicubicInterpolation resizers all with the same result.
Here is my method with my latest attempt. Depending on how much memory I give the JVM it sometimes fails on the resize, other times is fails on the toRGB():
private MBFImage scaleImage2(float scaleFactor) throws IOException {
FImage img2Flat = image2.flatten();
int width = (int)Math.round(img2Flat.getWidth() * scaleFactor);
int height = (int)Math.round(img2Flat.getHeight() * scaleFactor);
BilinearInterpolation resizer = new BilinearInterpolation(width, height, 1/scaleFactor);
resizer.processImage(img2Flat);
return img2Flat.toRGB();
}
Here is where I overlay the images:
private MBFImage createScaledOverlay() {
MBFImage scaledImg2 = null;
if(scaledLastCrop == null) {
try {
scaledLastCrop = scaleLastCrop();
} catch (IOException e) {
e.printStackTrace();
}
}
try {
scaledImg2 = scaleImage2(image2ScaleFactor);
} catch (IOException e) {
e.printStackTrace();
}
int img2ScaledPixelx = Math.round(image2SelectedPixel.x * image2ScaleFactor);
int img2ScaledPixely = Math.round(image2SelectedPixel.y * image2ScaleFactor);
int lastCropScaledPixelx = (int)Math.round(lastCropSelectedPixel.x * lastCropScaleFactor);
int lastCropScaledPixely = (int)Math.round(lastCropSelectedPixel.y * lastCropScaleFactor);
scaledImg2.overlayInplace(scaledLastCrop, img2ScaledPixelx - lastCropScaledPixelx, img2ScaledPixely - lastCropScaledPixely);
return scaledImg2;
}
I am ok with one of two paths forward:
Sometimes a solution is so obvious it is embarrassing.
My real goal, now that I think about it, is to find the scale factor between the two images. Instead of scaling up image2, I can scale down image1. This is much less memory intensive. Then with regards to image2 I can just invert this scale factor.