【问题标题】:Can't use fisheye lens effect on my image in Java无法在 Java 中对我的图像使用鱼眼镜头效果
【发布时间】:2014-01-13 01:20:26
【问题描述】:

我想在 Java 中使用fisheye lens algorithm,但我无法实现 main 方法。

this site的底部,我找到了实现鱼眼算法的java代码,但没有任何main()方法。我尝试自己实现一个 main() 方法,但到目前为止我只能显示图像,但我不能在该图像上使用 bucket() 方法,这应该会对我的图像产生鱼眼效果。

您能否更正我的主要方法,或者实现一个新方法,加载一些图像(bufferedImage),然后在该图像上使用桶()方法?

到目前为止我的代码是:

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);


}

}

代码正在运行,但它只显示图像。我想在我的图像上使用桶()方法,这将产生鱼眼效果。因为我是java新手,我做不到,请帮忙。

【问题讨论】:

    标签: java distortion fisheye


    【解决方案1】:

    参考这个网站:

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

    它包含文章末尾的概念和工作来源。

    【讨论】:

    • 谢谢!它看起来更简单,但也没有 main() 方法:D
    • 然后添加这个作为你的答案。
    【解决方案2】:

    让你的函数静态

    public static BufferedImage barrel (BufferedImage input, float k)
    

    改变

    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);   
        ...
        ...
    }
    

    【讨论】:

    • 感谢您回答我,但这不起作用。它只显示没有图像的应用程序窗口。
    • 你试过改变浮点值吗?我只是输入一个随机值。
    • 是的,我将其更改为 1 和 5,但没有帮助。恐怕那个算法有问题。
    • 是的,看起来。可能您应该看到一些与该功能相关的文档。顺便说一句,你的问题得到解答了吗?
    【解决方案3】:

    所以我终于实现了想要的鱼眼!只是因为thisthis 网站。对于有类似问题的任何人,我在这里给出的代码确实很乱但可以工作:

    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;
    }    
    
    }
    

    【讨论】:

      猜你喜欢
      • 2016-05-20
      • 2010-12-27
      • 1970-01-01
      • 2010-12-27
      • 1970-01-01
      • 1970-01-01
      • 2012-11-01
      • 2012-10-12
      相关资源
      最近更新 更多