2013-12-24 6 views
0

Я хочу использовать fisheye lens algorithm в Java, но я не могу реализовать основной метод.Невозможно использовать эффект линзы рыбий глаз на моем изображении в Java

В нижней части this site я нашел код java, который реализует алгоритм fisheye, но не было никакого метода main(). Я попытался реализовать метод main() самостоятельно, но до сих пор я просто могу отображать изображение, но я не могу использовать метод barrel() на этом изображении, что должно сделать эффект рыбий глаз на моем изображении.

Не могли бы вы исправить мой основной метод или реализовать новый, который загружает некоторое изображение (bufferedImage), а затем использует метод barrel() на этом изображении?

Мой код до сих пор:

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


} 

}

код работает, но отображать только изображение. Я хочу использовать метод barrel() на моем изображении, что сделает эффект рыбий глаз. Потому что я новичок в java, я не могу этого сделать, пожалуйста, помогите.

ответ

0

Так что я, наконец, внедрено желаемое фишай! Только из-за this и this сайт. Я даю здесь действительно грязный, но рабочий код для тех, у кого есть аналогичная проблема:

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

} 
1

сделать вашу функцию статического

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

Спасибо, что ответили на меня, но это не работает. Он отображает только окно приложения без изображения в нем. – user1920217

+0

Вы пытались изменить значение float? я просто ставлю случайное значение. – gaurav5430

+0

Да, я изменил его на 1, а также на 5, и это не поможет. Я боюсь, что есть проблема с этим алгоритмом. – user1920217

 Смежные вопросы

  • Нет связанных вопросов^_^