Skip to content

Instantly share code, notes, and snippets.

@ajmas
Last active January 20, 2016 23:18
Show Gist options
  • Save ajmas/6bce347f067d48de4c39 to your computer and use it in GitHub Desktop.
Save ajmas/6bce347f067d48de4c39 to your computer and use it in GitHub Desktop.
Takes a panoramic image that is in a 'fisheye' view and unwraps it. See http://terra-azure.org/?loc=articles/programming/java/polar2cartesian for an explanation
package ajmas74.experimental.graphics2d;
import java.awt.Image;
import java.awt.image.BufferedImage;
import java.awt.image.ColorModel;
import java.awt.image.DataBuffer;
import java.awt.image.DataBufferInt;
import java.awt.image.DirectColorModel;
import java.awt.image.PixelGrabber;
import java.awt.image.Raster;
import java.awt.image.WritableRaster;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
/**
* See http://terra-azure.org/?loc=articles/programming/java/polar2cartesian
* @author andre-john mas
*/
public class RolloutImage {
/**
* This takes a panoramic image that is in a 'fisheye' view and unwraps it. The method
* take an 'innerRadius' and an 'outerRadius' parameter. If your image contains a
* central area, that should be ignored, specify the radius, in pixels, of the area
* to be ignored, in the 'innerRadius' parameter, otherwise you can specify '0' as value.
*
*
* @param image the image to convert
* @param innerRadius the inner radius, representing the area with no significant data
* @param outerRadius the radius to which the image extends to
* @param newWidth the width of the new image
* @return converted image
*/
public static BufferedImage convertPolarImageToCartesian(Image image,
int innerRadius, int outerRadius, int newWidth) {
int imgWidth = image.getWidth(null);
int imgHeight = image.getHeight(null);
// Get this pixels from the original image //
int[] packedPixels = new int[imgWidth * imgHeight];
PixelGrabber pixelgrabber = new PixelGrabber(image, 0, 0, imgWidth,
imgHeight, packedPixels, 0, imgWidth);
try {
pixelgrabber.grabPixels();
} catch (InterruptedException e) {
throw new RuntimeException();
}
int width = newWidth;
int height = outerRadius - innerRadius;
int size = width * height;
int[] pixelData = new int[size];
// Get the center point of the image //
int xc = imgWidth / 2;
int yc = imgHeight / 2;
// Do the conversion //
for (int r = innerRadius; r < outerRadius; r++) {
// t = theta in degrees
for (int t = 0; t < width; t++) {
// theta in radians
double tr = Math.toRadians((t * 1.0) / width * 360);
int x = (int) Math.round(xc + r * Math.cos(tr));
int y = (int) Math.round(yc + r * Math.sin(tr));
int rDiff = r - innerRadius;
int h = width * (height - (rDiff + 1));
pixelData[h + t] = packedPixels[imgWidth * y + x];
}
}
DataBuffer dataBuf = new DataBufferInt(pixelData, size);
ColorModel colorModel = new DirectColorModel(32, 0x00ff0000,
0x0000ff00, 0x000000ff);
int[] masks = { 0x00ff0000, 0x0000ff00, 0x000000ff };
WritableRaster raster = Raster.createPackedRaster(dataBuf, width,
height, width, masks, null);
BufferedImage convertedImage = new BufferedImage(colorModel, raster,
false, null);
return convertedImage;
}
public static Image loadImage(String filePath) throws IOException {
return ImageIO.read(new File(filePath));
}
public static void main(String[] args) throws Exception {
// TODO Auto-generated method stub
Image image = ImageIO.read(new File("data/circular-panormaic.jpg"));
BufferedImage convertedImage = convertPolarImageToCartesian(
image, 1, 510, 510);
File outputfile = new File("data/out.png");
ImageIO.write(convertedImage, "png", outputfile);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment