Skip to content

Instantly share code, notes, and snippets.

@hageldave
Last active March 22, 2019 00:39
Show Gist options
  • Save hageldave/0bf84b6e1bad76cbf3f764c3a29be9d5 to your computer and use it in GitHub Desktop.
Save hageldave/0bf84b6e1bad76cbf3f764c3a29be9d5 to your computer and use it in GitHub Desktop.
RGB Radon Transform of Images
package radon;
import java.util.function.DoubleBinaryOperator;
import hageldave.imagingkit.core.Img;
import hageldave.imagingkit.core.io.ImageLoader;
import hageldave.imagingkit.core.io.ImageSaver;
import hageldave.imagingkit.core.scientific.ColorImg;
import hageldave.imagingkit.core.util.ImageFrame;
public class RadonTransform {
public static void main(String[] args) {
// ColorImg img = new ColorImg(300, 300, false);
// img.paint(g2d -> {
// g2d.setColor(Color.WHITE);
// g2d.fillRect(40, 20, 100, 170);
// });
Img loadedImg = ImageLoader.loadImgFromURL("https://upload.wikimedia.org/wikipedia/commons/5/5e/Lobster.jpg");
ColorImg img = new ColorImg(loadedImg, false);
ImageFrame.display(img.getRemoteBufferedImage());
DoubleBinaryOperator samplerr = new DoubleBinaryOperator() {
@Override
public double applyAsDouble(double x, double y) {
x = (x+1.0)/2.0;
y = (y+1.0)/2.0;
if(x < 0 || x > 1 || y < 0 || y > 1){
return 0;
}
return img.interpolate(ColorImg.channel_r, x, y);
}
};
DoubleBinaryOperator samplerg = new DoubleBinaryOperator() {
@Override
public double applyAsDouble(double x, double y) {
x = (x+1.0)/2.0;
y = (y+1.0)/2.0;
if(x < 0 || x > 1 || y < 0 || y > 1){
return 0;
}
return img.interpolate(ColorImg.channel_g, x, y);
}
};
DoubleBinaryOperator samplerb = new DoubleBinaryOperator() {
@Override
public double applyAsDouble(double x, double y) {
x = (x+1.0)/2.0;
y = (y+1.0)/2.0;
if(x < 0 || x > 1 || y < 0 || y > 1){
return 0;
}
return img.interpolate(ColorImg.channel_b, x, y);
}
};
ColorImg target = new ColorImg(300,600,false);
transform(samplerr, samplerg, samplerb, target);
ImageFrame.display(target.getRemoteBufferedImage());
ImageSaver.saveImage(target.toBufferedImage(), "lobster_radon.png");
}
public static void transform(
DoubleBinaryOperator sampler2dr,
DoubleBinaryOperator sampler2dg,
DoubleBinaryOperator sampler2db,
ColorImg targetImg)
{
targetImg.forEach(true, pixel -> {
// alpha in 0..2pi
double alpha = pixel.getY() * Math.PI * 2.0 / targetImg.getHeight();
// s in -1..1
double s = pixel.getX() * 2.0/targetImg.getWidth() -1.0;
s *= 1.5;
double sumr=0, sumg=0, sumb=0;
int integration_steps = 500;
for(int z_i = 0; z_i < integration_steps; z_i++){
// z in -1..1
double z = z_i * 2.0 / integration_steps -1;
double x = z*Math.sin(alpha) + s * Math.cos(alpha);
double y = -z*Math.cos(alpha) + s * Math.sin(alpha);
sumr += sampler2dr.applyAsDouble(x, y);
sumg += sampler2dg.applyAsDouble(x, y);
sumb += sampler2db.applyAsDouble(x, y);
}
sumr /= integration_steps;
sumg /= integration_steps;
sumb /= integration_steps;
pixel.setRGB_fromDouble(sumr, sumg, sumb);
});
targetImg.forEach(px -> {
double r = clamp((px.r_asDouble()-0.5)* 1.5 + 0.5, 0, 1);
double g = clamp((px.g_asDouble()-0.5)* 1.5 + 0.5, 0, 1);
double b = clamp((px.b_asDouble()-0.5)* 1.5 + 0.5, 0, 1);
px.setRGB_fromDouble(r, g, b);
});
}
static double clamp(double v, double lower, double upper) {
return Math.max(lower, Math.min(upper, v));
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment