Question

I want to use fisheye lens algorithm in Java, but I can't implement a main method.

At the bottom of this site, I found java code, that implements fisheye algorithm, but there wasn't any main() method. I've tried to implement a main() method by my own, but so far I just can display image, but I can't use the barrel() method on that image which should make fisheye effect on my image.

Could you please correct my main method, or implement a new one, that loads some image(bufferedImage) and then use barrel() method on that image?

My code so far is:

import java.awt.FlowLayout;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;

public class DisplayImage {
float xscale;
float yscale;
float xshift;
float yshift;
int [] s;                             


public BufferedImage barrel (BufferedImage input, float k){

    float centerX=input.getWidth()/2; //center of distortion
    float centerY=input.getHeight()/2;

    int width = input.getWidth(); //image bounds
    int height = input.getHeight();

    BufferedImage dst = new BufferedImage(width, height,BufferedImage.TYPE_INT_ARGB); //output pic

      xshift = calc_shift(0,centerX-1,centerX,k);
      float newcenterX = width-centerX;
      float xshift_2 = calc_shift(0,newcenterX-1,newcenterX,k);

      yshift = calc_shift(0,centerY-1,centerY,k);
      float newcenterY = height-centerY;
      float yshift_2 = calc_shift(0,newcenterY-1,newcenterY,k);

      xscale = (width-xshift-xshift_2)/width;
      yscale = (height-yshift-yshift_2)/height;

      for(int j=0;j<dst.getHeight();j++){
          for(int i=0;i<dst.getWidth();i++){
            float x = getRadialX((float)i,(float)j,centerX,centerY,k);
            float y = getRadialY((float)i,(float)j,centerX,centerY,k);
            sampleImage(input,x,y);
            int color = ((s[1]&0x0ff)<<16)|((s[2]&0x0ff)<<8)|(s[3]&0x0ff);
//            System.out.print(i+" "+j+" \\");

            dst.setRGB(i, j, color);

          }
        }
    return dst;
}

void sampleImage(BufferedImage arr, float idx0, float idx1)
{
    s = new int [4];
  if(idx0<0 || idx1<0 || idx0>(arr.getHeight()-1) || idx1>(arr.getWidth()-1)){
    s[0]=0;
    s[1]=0;
    s[2]=0;
    s[3]=0;
    return;
  }

  float idx0_fl=(float) Math.floor(idx0);
  float idx0_cl=(float) Math.ceil(idx0);
  float idx1_fl=(float) Math.floor(idx1);
  float idx1_cl=(float) Math.ceil(idx1);

  int [] s1 = getARGB(arr,(int)idx0_fl,(int)idx1_fl);
  int [] s2 = getARGB(arr,(int)idx0_fl,(int)idx1_cl);
  int [] s3 = getARGB(arr,(int)idx0_cl,(int)idx1_cl);
  int [] s4 = getARGB(arr,(int)idx0_cl,(int)idx1_fl);

  float x = idx0 - idx0_fl;
  float y = idx1 - idx1_fl;

  s[0]= (int) (s1[0]*(1-x)*(1-y) + s2[0]*(1-x)*y + s3[0]*x*y + s4[0]*x*(1-y));
  s[1]= (int) (s1[1]*(1-x)*(1-y) + s2[1]*(1-x)*y + s3[1]*x*y + s4[1]*x*(1-y));
  s[2]= (int) (s1[2]*(1-x)*(1-y) + s2[2]*(1-x)*y + s3[2]*x*y + s4[2]*x*(1-y));
  s[3]= (int) (s1[3]*(1-x)*(1-y) + s2[3]*(1-x)*y + s3[3]*x*y + s4[3]*x*(1-y));
}

int [] getARGB(BufferedImage buf,int x, int y){
    int rgb = buf.getRGB(x, y); // Returns by default ARGB.
    int [] scalar = new int[4];
    scalar[0] = (rgb >>> 24) & 0xFF;
    scalar[1] = (rgb >>> 16) & 0xFF;
    scalar[2] = (rgb >>> 8) & 0xFF;
    scalar[3] = (rgb >>> 0) & 0xFF;
    return scalar;
}

float getRadialX(float x,float y,float cx,float cy,float k){
  x = (x*xscale+xshift);
  y = (y*yscale+yshift);
  float res = x+((x-cx)*k*((x-cx)*(x-cx)+(y-cy)*(y-cy)));
  return res;
}

float getRadialY(float x,float y,float cx,float cy,float k){
  x = (x*xscale+xshift);
  y = (y*yscale+yshift);
  float res = y+((y-cy)*k*((x-cx)*(x-cx)+(y-cy)*(y-cy)));
  return res;
}

float thresh = 1;

float calc_shift(float x1,float x2,float cx,float k){
  float x3 = (float)(x1+(x2-x1)*0.5);
  float res1 = x1+((x1-cx)*k*((x1-cx)*(x1-cx)));
  float res3 = x3+((x3-cx)*k*((x3-cx)*(x3-cx)));

  if(res1>-thresh && res1 < thresh)
    return x1;
  if(res3<0){
    return calc_shift(x3,x2,cx,k);
  }
  else{
    return calc_shift(x1,x3,cx,k);
  }
}



public static void main(String avg[]) throws IOException
{
    BufferedImage img=ImageIO.read(new File("image.jpg"));       
    ImageIcon icon=new ImageIcon(img);   
    JFrame frame=new JFrame();
    frame.setLayout(new FlowLayout());
    frame.setSize(625,648);
    JLabel lbl=new JLabel();
    lbl.setIcon(icon);
    frame.add(lbl);
    frame.setVisible(true);
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);


}

}

Code is working, but it only display image. I want to use barrel() method on my image, which will do the fisheye effect. Because I am newbie to java, I can't do that, please help.

Was it helpful?

Solution 3

So I finally implemented desired fisheye! Just because of this and this site. I am giving here really messy but working code for anyone with similar problem:

package fisheye;

import java.awt.image.BufferedImage;
import java.awt.image.WritableRaster;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;

public class DitherMain {

   static String imageString = "image.bmp";

   BufferedImage startImage, endImage;
   int[] startPixels, endPixels, imR, imG, imB;
   int width, height;

   public static void main(String[] args){
      new DitherMain(loadImage(imageString));
   }

   //this object transforms the old image and writes the new image
   DitherMain(BufferedImage img){
      //filing the image into startpixels
      startImage = img;
      width = img.getWidth();
      height = img.getHeight();
      startPixels = new int[width*height];
      img.getRGB(0, 0, width, height, startPixels, 0, width);

      endPixels = fisheye(startPixels, width, height);

      transformPixels();

      WritableRaster wRaster = endImage.getData().createCompatibleWritableRaster();

      wRaster.setSamples(0, 0, width, height, 0, imR);
      wRaster.setSamples(0, 0, width, height, 1, imG);
      wRaster.setSamples(0, 0, width, height, 2, imB);

      endImage.setData(wRaster);
      System.out.println(endImage);

      //writing the file for endImage into the harddrive
      writeFile();
   }

   void transformPixels(){
      //endPixels = startPixels;
      endImage = startImage;

      imR = new int[endPixels.length];
      imG = new int[endPixels.length];
      imB = new int[endPixels.length];

      for(int i = 0; i < endPixels.length; i++){
         imR[i] = (endPixels[i] >> 16) & 0x000000FF;
         imG[i] = (endPixels[i] >> 8) & 0x000000FF;
         imB[i] = endPixels[i] & 0x000000FF;
      }
   }

   void writeFile(){
      try {
         ImageIO.write(endImage,"BMP",new File("RESULT.bmp"));
      } catch (IOException e) {
         e.printStackTrace();
      }
   }

   //this method just loads a specific buffered image
   public static BufferedImage loadImage(String fileName){   
      BufferedImage img;

      try{
         img=ImageIO.read(new File("image.bmp"));
         //img = ImageIO.read(DitherMain.class.getResource(fileName));
      } catch (Exception e) {
         e.printStackTrace();
         throw new RuntimeException(e);
      }
      return img;
   }

public static int[] fisheye(int[] srcpixels, double w, double h) {

    /*
     *    Fish eye effect
     *    tejopa, 2012-04-29
     *    http://popscan.blogspot.com
     *    http://www.eemeli.de
     */

    // create the result data
    int[] dstpixels = new int[(int)(w*h)];            
    // for each row
    for (int y=0;y<h;y++) {                                
        // normalize y coordinate to -1 ... 1
        double ny = ((2*y)/h)-1;                        
        // pre calculate ny*ny
        double ny2 = ny*ny;                                
        // for each column
        for (int x=0;x<w;x++) {                            
            // normalize x coordinate to -1 ... 1
            double nx = ((2*x)/w)-1;                    
            // pre calculate nx*nx
            double nx2 = nx*nx;
            // calculate distance from center (0,0)
            // this will include circle or ellipse shape portion
            // of the image, depending on image dimensions
            // you can experiment with images with different dimensions
            double r = Math.sqrt(nx2+ny2);                
            // discard pixels outside from circle!
            if (0.0<=r&&r<=1.0) {                            
                double nr = Math.sqrt(1.0-r*r);            
                // new distance is between 0 ... 1
                nr = (r + (1.0-nr)) / 2.0;
                // discard radius greater than 1.0
                if (nr<=1.0) {
                    // calculate the angle for polar coordinates
                    double theta = Math.atan2(ny,nx);         
                    // calculate new x position with new distance in same angle
                    double nxn = nr*Math.cos(theta);        
                    // calculate new y position with new distance in same angle
                    double nyn = nr*Math.sin(theta);        
                    // map from -1 ... 1 to image coordinates
                    int x2 = (int)(((nxn+1)*w)/2.0);        
                    // map from -1 ... 1 to image coordinates
                    int y2 = (int)(((nyn+1)*h)/2.0);        
                    // find (x2,y2) position from source pixels
                    int srcpos = (int)(y2*w+x2);            
                    // make sure that position stays within arrays
                    if (srcpos>=0 & srcpos < w*h) {
                        // get new pixel (x2,y2) and put it to target array at (x,y)
                        dstpixels[(int)(y*w+x)] = srcpixels[srcpos];    
                    }
                }
            }
        }
    }
    //return result pixels
    return dstpixels;
}    

}

OTHER TIPS

Refer to this site:

http://popscan.blogspot.in/2012/04/fisheye-lens-equation-simple-fisheye.html

It contains the concept as well as working source at the end of the article.

make your function static

public static BufferedImage barrel (BufferedImage input, float k)

and change

public static void main(String avg[]) throws IOException
{ 
    BufferedImage img=ImageIO.read(new File("image.jpg"));

    //now pass this image to your barrel method and return in new image
    //note that, method can be called now without instatntiating any object, as it is static now
    BufferImage barrelImage = barrel(img,2.0);       
    ImageIcon icon=new ImageIcon(barrelImage);   
    ...
    ...
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top