8

魚眼レンズ エフェクトを作成する方法を探しています。openCV で魚眼歪みをシミュレートすることは可能ですか?

openCVでできるとしたら、openGLと比べてどちらが良い結果が得られるのでしょうか? ありがとう。

4

5 に答える 5

15

このアプリは opencv を使用して作成しました。これはあなたが言及している効果ですか?基本的に、ウィキペディアの「歪み(光学)」に示されている式をコーディングしました。必要に応じてコードを表示できます

更新: OK、以下は opencv を使用して c++ で記述された実際のコードです (文書化されていないため、お気軽に説明を求めてください): プログラムは次のパラメーターを入力として受け取ります: | 入力画像| | | 出力画像| | | 歪みの量を制御する K (通常は 0.001 前後の値を試してください) | | | 歪みの中心の x 座標| | | 歪みの中心の y 座標|

したがって、プログラムの核心は、結果の画像でピクセルごとに反復し、放射状の歪みの式を使用して入力画像で一致するピクセルを探す二重の forループです (これは、画像ワーピングが一般的に行われる方法です - おそらく直感に反する方法です)。出力から入力への逆投影による)。出力画像のスケールに関係する微妙な点がいくつかあります (このプログラムでは、結果の画像は入力と同じサイズになります)。詳細を知りたい場合を除き、ここでは説明しません。お楽しみください。

    #include <cv.h>
    #include <highgui.h>
    #include <math.h>
    #include <unistd.h>
    #include <getopt.h>
    #include <iostream>


    void sampleImage(const IplImage* arr, float idx0, float idx1, CvScalar& res)
    {
      if(idx0<0 || idx1<0 || idx0>(cvGetSize(arr).height-1) || idx1>(cvGetSize(arr).width-1)){
        res.val[0]=0;
        res.val[1]=0;
        res.val[2]=0;
        res.val[3]=0;
        return;
      }
      float idx0_fl=floor(idx0);
      float idx0_cl=ceil(idx0);
      float idx1_fl=floor(idx1);
      float idx1_cl=ceil(idx1);

      CvScalar s1=cvGet2D(arr,(int)idx0_fl,(int)idx1_fl);
      CvScalar s2=cvGet2D(arr,(int)idx0_fl,(int)idx1_cl);
      CvScalar s3=cvGet2D(arr,(int)idx0_cl,(int)idx1_cl);
      CvScalar s4=cvGet2D(arr,(int)idx0_cl,(int)idx1_fl);
      float x = idx0 - idx0_fl;
      float y = idx1 - idx1_fl;
      res.val[0]= s1.val[0]*(1-x)*(1-y) + s2.val[0]*(1-x)*y + s3.val[0]*x*y + s4.val[0]*x*(1-y);
      res.val[1]= s1.val[1]*(1-x)*(1-y) + s2.val[1]*(1-x)*y + s3.val[1]*x*y + s4.val[1]*x*(1-y);
      res.val[2]= s1.val[2]*(1-x)*(1-y) + s2.val[2]*(1-x)*y + s3.val[2]*x*y + s4.val[2]*x*(1-y);
      res.val[3]= s1.val[3]*(1-x)*(1-y) + s2.val[3]*(1-x)*y + s3.val[3]*x*y + s4.val[3]*x*(1-y);
    }

    float xscale;
    float yscale;
    float xshift;
    float yshift;

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

      //  std::cerr<<"x1: "<<x1<<" - "<<res1<<" x3: "<<x3<<" - "<<res3<<std::endl;

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

    int main(int argc, char** argv)
    {
      IplImage* src = cvLoadImage( argv[1], 1 );
      IplImage* dst = cvCreateImage(cvGetSize(src),src->depth,src->nChannels);
      IplImage* dst2 = cvCreateImage(cvGetSize(src),src->depth,src->nChannels);
      float K=atof(argv[3]);
      float centerX=atoi(argv[4]);
      float centerY=atoi(argv[5]);
      int width = cvGetSize(src).width;
      int height = cvGetSize(src).height;

      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);
      //  scale = (centerX-xshift)/centerX;
      xscale = (width-xshift-xshift_2)/width;
      yscale = (height-yshift-yshift_2)/height;

      std::cerr<<xshift<<" "<<yshift<<" "<<xscale<<" "<<yscale<<std::endl;
      std::cerr<<cvGetSize(src).height<<std::endl;
      std::cerr<<cvGetSize(src).width<<std::endl;

      for(int j=0;j<cvGetSize(dst).height;j++){
        for(int i=0;i<cvGetSize(dst).width;i++){
          CvScalar s;
          float x = getRadialX((float)i,(float)j,centerX,centerY,K);
          float y = getRadialY((float)i,(float)j,centerX,centerY,K);
          sampleImage(src,y,x,s);
          cvSet2D(dst,j,i,s);

        }
      }
    #if 0
      cvNamedWindow( "Source1", 1 );
      cvShowImage( "Source1", dst);
      cvWaitKey(0);
    #endif

      cvSaveImage(argv[2],dst,0);

    #if 0
      for(int j=0;j<cvGetSize(src).height;j++){
        for(int i=0;i<cvGetSize(src).width;i++){
          CvScalar s;
          sampleImage(src,j+0.25,i+0.25,s);
          cvSet2D(dst,j,i,s);
        }
      }

      cvNamedWindow( "Source1", 1 );
      cvShowImage( "Source1", src);
      cvWaitKey(0);

    #endif  

}
于 2009-12-19T21:05:34.623 に答える
4

このコードについては、上記の 2 に感謝します。BufferedImage の代わりに Bitmaps を使用するように、上記の転写されたコードを Java で変更しました。これにより、コードを Android (AWT をサポートしていない) で実行できるようになります。また、ビットマップ全体ではなく円内のピクセルを操作する効果を作成しました。これにより、魚眼レンズの「レンズ」効果が得られます。これがすべての Android 開発者に役立つことを願っています。

import android.graphics.Bitmap;
import android.util.Log;

class Filters{
    float xscale;
    float yscale;
    float xshift;
    float yshift;
    int [] s;
    private String TAG = "Filters";
    public Filters(){

        Log.e(TAG, "***********inside constructor");
    }

    public Bitmap barrel (Bitmap input, float k){
        Log.e(TAG, "***********inside barrel method ");
        float centerX=input.getWidth()/2; //center of distortion
        float centerY=input.getHeight()/2;

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

        Bitmap dst = Bitmap.createBitmap(width, height,input.getConfig() ); //output pic
        Log.e(TAG, "***********dst bitmap created ");
          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;
          Log.e(TAG, "***********about to loop through bm");
          /*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.setPixel(i, j, color);

              }
            }*/

          int origPixel; // the pixel in orig image

          for(int j=0;j<dst.getHeight();j++){
              for(int i=0;i<dst.getWidth();i++){
                 origPixel= input.getPixel(i,j);
                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+" \\");


// check whether a pixel is within the circle bounds of 150

                if( Math.sqrt( Math.pow(i - centerX, 2) + ( Math.pow(j - centerY, 2) ) ) <= 150 ){
                dst.setPixel(i, j, color);
                }else{
                    dst.setPixel(i,j,origPixel);
                }
              }
            }
        return dst;
    }

    void sampleImage(Bitmap 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(Bitmap buf,int x, int y){
        int rgb = buf.getPixel(y, x); // 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);
      }
    }
}

.

import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.FutureTask;

import android.graphics.Bitmap;
import android.graphics.drawable.BitmapDrawable;
import android.os.Debug;
import android.util.Log;

public class MultiRuntimeProcessorFilter {



    private static final String TAG = "mrpf";
    private int x = 0;
    private Bitmap input = null;
    private int radius;


    public void createBitmapSections(int nOp, int[] sections){

        int processors = nOp;
        int jMax = input.getHeight();
        int aSectionSize = (int) Math.ceil(jMax/processors);
        Log.e(TAG, "++++++++++ sections size = "+aSectionSize);


        int k = 0;
        for(int h=0; h<processors+1; h++){

                sections[h] = k;
                k+= aSectionSize;



        }
    }// end of createBitmapSections()



    @SuppressWarnings("unchecked")
    public Bitmap barrel (Bitmap input, float k, int r){
          this.radius = r;
          this.input = input;
          int []arr = new int[input.getWidth()*input.getHeight()];


          Log.e(TAG, "bitmap height = "+input.getHeight()); 




          int nrOfProcessors = Runtime.getRuntime().availableProcessors();
          Log.e(TAG, "no of processors = "+nrOfProcessors);

          int[] sections = new int[nrOfProcessors+1];


          createBitmapSections(nrOfProcessors,sections);
          ExecutorService threadPool = Executors.newFixedThreadPool(nrOfProcessors);

          for(int g=0; g<sections.length;g++){
              Log.e(TAG, "++++++++++ sections= "+sections[g]);
          }

         // ExecutorService threadPool = Executors.newFixedThreadPool(nrOfProcessors);

          Object[] task = new Object[nrOfProcessors];

          for(int z = 0; z < nrOfProcessors; z++){
             task[z]  = (FutureTask<PartialResult>) threadPool.submit(new PartialProcessing(sections[z], sections[z+1] - 1, input, k));  
             Log.e(TAG, "++++++++++ task"+z+"= "+task[z].toString()); 
          }

         PartialResult[] results = new PartialResult[nrOfProcessors];

         try{
              for(int t = 0; t < nrOfProcessors; t++){

                  results[t] = ((FutureTask<PartialResult>) task[t]).get();

                  results[t].fill(arr);
              }

          }catch(Exception e){
              e.printStackTrace();
          }

          Bitmap dst2 = Bitmap.createBitmap(arr,input.getWidth(),input.getHeight(),input.getConfig());


        return dst2;


        }//end of barrel()




    public class PartialResult {
           int startP;
           int endP;
           int[] storedValues;

           public PartialResult(int startp, int endp, Bitmap input){

               this.startP = startp;
               this.endP = endp;
               this.storedValues = new int[input.getWidth()*input.getHeight()];


           }

           public void addValue(int p, int result) {
                 storedValues[p] = result;

           }

           public void fill(int[] arr) {



              for (int p = startP; p < endP; p++){
                  for(int b=0;b<radius;b++,x++)
                 arr[x] = storedValues[x];

              } 
              Log.e(TAG, "++++++++++ x ="+x);
              }

           }//end of partialResult




    public class PartialProcessing implements Callable<PartialResult> {
        int startJ;
        int endJ;


        private int[] scalar;
        private float xscale;
        private float yscale;
        private float xshift;
        private float yshift;
        private float thresh = 1;
        private int [] s1;
        private int [] s2;
        private int [] s3;
        private int [] s4;
        private int [] s;
        private Bitmap input;
        private float k;



        public PartialProcessing(int startj, int endj, Bitmap input, float k) {

            this.startJ = startj;
            this.endJ = endj;
            this.input = input;
            this.k = k;

            s = new int[4];
            scalar = new int[4];
            s1 = new int[4];
            s2 = new int[4];
            s3 = new int[4];
            s4 = new int[4];

        }

        int [] getARGB(Bitmap buf,int x, int y){

            int rgb = buf.getPixel(y, x); // 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 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);
            }
          }


          void sampleImage(Bitmap 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);



             s1 = getARGB(arr,(int)idx0_fl,(int)idx1_fl);
             s2 = getARGB(arr,(int)idx0_fl,(int)idx1_cl);
             s3 = getARGB(arr,(int)idx0_cl,(int)idx1_cl);
             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));


          }



        @Override public PartialResult call() { 

             PartialResult partialResult = new PartialResult(startJ, endJ,input);

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



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



              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;


            int p = startJ*radius; 
            int origPixel = 0;
            int color = 0;
            int i;

            for (int j = startJ; j <  endJ; j++){

                for ( i = 0; i < width; i++, p++){


             origPixel = input.getPixel(i,j);

             float x = getRadialX((float)j,(float)i,centerX,centerY,k);


             float y = getRadialY((float)j,(float)i,centerX,centerY,k);

             sampleImage(input,x,y);

             color = ((s[1]&0x0ff)<<16)|((s[2]&0x0ff)<<8)|(s[3]&0x0ff);
            //Log.e(TAG, "radius = "+radius);

             if(((i-centerX)*(i-centerX) + (j-centerY)*(j-centerY)) <= radius*(radius/4)){

                                 partialResult.addValue(p, color);


            }else{


                partialResult.addValue(p, origPixel);



            }

                }//end of inner for

        }//end of outer for

            return partialResult;
    }//end of call


}// end of partialprocessing

}//end of MultiProcesorFilter

約束通り@And_Dev

以下は、ユーザーのタッチ座標を取得し、選択した領域でフィルターを呼び出すビューです。選択された領域は、円の中心と半径 (円) などのコードです。このコードは、豊胸アプリの場合と同じようにこれを 2 回実行します:) これは必要ないので、Horizo​​ntalSlider コードをコメント アウトするだけです。

import java.io.BufferedInputStream;
import java.io.DataInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.PorterDuff.Mode;
import android.graphics.PorterDuffXfermode;
import android.os.Environment;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;

import com.tecmark.HorizontalSlider.OnProgressChangeListener;

public class TouchView extends View{


    private File tempFile;
    private byte[] imageArray;
    private Bitmap bgr;

    private Bitmap crop;
    private Bitmap crop2;
    private Bitmap overLay;
    private Bitmap overLay2;


    private float centreX;
    private float centreY;
    private float centreA = 200;
    private float centreB = 200;
    private Boolean xyFound = false;
    private int Progress = 1;
    private static final String TAG = "*********TouchView";
    private Filters f = null;
    private boolean bothCirclesInPlace = false;
    private MultiProcessorFilter mpf;
    private MultiProcessorFilter mpf2;
    private MultiRuntimeProcessorFilter mrpf;
    private MultiRuntimeProcessorFilter mrpf2;





    public TouchView(Context context) {
        super(context);

    }




    public TouchView(Context context, AttributeSet attr) {
        super(context,attr);
        Log.e(TAG, "++++++++++ inside touchview constructor");



        tempFile = new File(Environment.getExternalStorageDirectory().
                getAbsolutePath() + "/"+"image.jpg");

        imageArray = new byte[(int)tempFile.length()];


     try{

            InputStream is = new FileInputStream(tempFile);
            BufferedInputStream bis = new BufferedInputStream(is);
            DataInputStream dis = new DataInputStream(bis);


            int i = 0;

            while (dis.available() > 0) {
            imageArray[i] = dis.readByte();
            i++;
            }

            dis.close();

       } catch (Exception e) {

               e.printStackTrace();
            }


       Bitmap bm = BitmapFactory.decodeByteArray(imageArray, 0, imageArray.length);




        bgr = bm.copy(bm.getConfig(), true);;

        overLay = null;
        overLay2 = null;



       bm.recycle();

    }// end of touchView constructor




    public void findCirclePixels(){ 

         //  f = new Filters();
         //  mpf = new MultiProcessorFilter();
         //  mpf2 = new MultiProcessorFilter();
         mrpf = new MultiRuntimeProcessorFilter();
         mrpf2 = new MultiRuntimeProcessorFilter();

         crop = Bitmap.createBitmap(bgr,Math.max((int)centreX-75,0),Math.max((int)centreY-75,0),150,150);
         crop2 = Bitmap.createBitmap(bgr,Math.max((int)centreA-75,0),Math.max((int)centreB-75,0),150,150);

              new Thread(new Runnable() {
                public void run() {
                    float prog = (float)Progress/150001;

               // final Bitmap bgr3 = f.barrel(crop,prog);
               // final Bitmap bgr4 = f.barrel(crop2,prog);

              //  final Bitmap bgr3 = mpf.barrel(crop,prog);
              //  final Bitmap bgr4 = mpf2.barrel(crop2,prog);

                    final Bitmap bgr3 = mrpf.barrel(crop,prog);
                    final Bitmap bgr4 = mrpf2.barrel(crop2,prog);

                  TouchView.this.post(new Runnable() {
                    public void run() {


                      TouchView.this.overLay = bgr3;
                      TouchView.this.overLay2 = bgr4;

                      TouchView.this.invalidate();

                    }
                  });
                }
              }).start();


        }// end of changePixel()






    @Override
    public boolean onTouchEvent(MotionEvent ev) {

        switch (ev.getAction()) {

            case MotionEvent.ACTION_DOWN: {

                if(xyFound == false){
                centreX = (int) ev.getX();
                centreY = (int) ev.getY();
                xyFound = true;
                }else{
                centreA = (int) ev.getX();
                centreB = (int) ev.getY();
                bothCirclesInPlace  = true;
                }


                break;
            }

          /*  case MotionEvent.ACTION_MOVE: {

                if(xyFound == false){
                    centreX = (int) ev.getX();
                    centreY = (int) ev.getY();
                    xyFound = true;
                }else{
                    centreA = (int) ev.getX();
                    centreB = (int) ev.getY();
                    bothCirclesInPlace = true;
                    }

                    findCirclePixels();
                 // TouchView.this.invalidate();
                    break;

            }*/           

            case MotionEvent.ACTION_UP: 

                break;

        }
        return true;
    }//end of onTouchEvent





    public void initSlider(final HorizontalSlider slider)
    {

        slider.setOnProgressChangeListener(changeListener);


    }



    private OnProgressChangeListener changeListener = new OnProgressChangeListener() {


        @Override
        public void onProgressChanged(View v, int progress) {



              setProgress(progress);



        }
    };




    @Override
    public void onDraw(Canvas canvas){
        super.onDraw(canvas);

        Log.e(TAG, "******about to draw bgr ");
        canvas.drawBitmap(bgr, 0, 0, null);

        if(bothCirclesInPlace == true){

                if(overLay != null){
                    Log.e(TAG, "******about to draw overlay1 ");
        canvas.drawBitmap(overLay, centreX-75, centreY-75, null);
                }
            if(overLay2 != null){
                Log.e(TAG, "******about to draw overlay2 ");
        canvas.drawBitmap(overLay2, centreA-75, centreB-75, null);
            }

        }

    }//end of onDraw




    protected void setProgress(int progress2) {
        Log.e(TAG, "***********in SETPROGRESS");
        this.Progress = progress2;



        findCirclePixels();


    }




}

.

呼び出しアクティビティ。

import android.app.Activity;
import android.os.AsyncTask;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.Window;
import android.view.WindowManager;
import android.view.View.OnClickListener;
import android.widget.Button;

public class Jjilapp extends Activity {




    private static final String TAG = "*********jjil";


    @Override 
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        requestWindowFeature(Window.FEATURE_NO_TITLE);
        getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
                WindowManager.LayoutParams.FLAG_FULLSCREEN);

        setContentView(R.layout.touchview);
        final TouchView touchView = (TouchView)findViewById(R.id.touchview); 
        final HorizontalSlider slider = (HorizontalSlider)findViewById(R.id.slider); 

        touchView.initSlider(slider);




    }//end of oncreate




}

助けが必要な場合は、仲間に尋ねてください。お役に立てれば

于 2011-06-08T15:05:57.620 に答える
2

そのコードをありがとう。とても助かります。Java用に暗号化しました。多分誰かが接線方向の歪みをシミュレートするための同様の機能を持っていますか?

import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
import com.jhlabs.image.InterpolateFilter;

class Filters{
    float xscale;
    float yscale;
    float xshift;
    float yshift;
    int [] s;
    public Filters(){

    }

    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_RGB); //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);
      }
    }
}
于 2011-04-26T13:48:20.217 に答える
1

Java ファイルをデバッグしたところ、携帯電話 (4.0 以上) で正常に動作しました。3 つの Java ファイルと 1 つの xml ファイルで構成されます。drawaable ディレクトリの下に checkerboardback.jpg ファイルを配置する必要があります。誰かが言ったように、アルファ値が欠落していたので、「0x0ff」を付けました。また、一部の Looping の上限が間違っていました。

//1. MultiRuntimeProcessorFilter.java

public class MultiRuntimeProcessorFilter {



private static final String TAG = "mrpf";
private int x = 0;
private Bitmap input = null;
private int radius;
private int mHeight;


public void createBitmapSections(int nOp, int[] sections){

    int processors = nOp;
    int jMax = input.getHeight();
    int aSectionSize = (int) Math.ceil(jMax/processors);
    Log.e("yoSIZECHK", "++++++++++ sections size = "+aSectionSize);

    int k = 0;
    for(int h=0; h<processors+1; h++){

            sections[h] = k;
            k+= aSectionSize;
            if(h==processors){
                sections[h] = mHeight;//Last must cover ceiling
            }
        Log.v("yoSEC","sections = "+h+" "+sections[h]);

    }
}// end of createBitmapSections()


//@SuppressWarnings("unchecked")
public Bitmap barrel (Bitmap input, float k, int r){
      this.radius = r;
      this.input = input;
      int []mArray = new int[input.getWidth()*input.getHeight()];

      mHeight = input.getHeight();
      Log.e(TAG, "bitmap height x width = "+mHeight+" "+input.getWidth());
  //Log.v("yoRESULT", "height width = "+ input.getWidth()+" "+input.getHeight());




      int nrOfProcessors = Runtime.getRuntime().availableProcessors();
      Log.e(TAG, "no of processors = "+nrOfProcessors);


      int[] sections = new int[nrOfProcessors+1];


      createBitmapSections(nrOfProcessors,sections);
      ExecutorService threadPool = Executors.newFixedThreadPool(nrOfProcessors);

      for(int g=0; g<sections.length;g++){
          Log.e(TAG, "++++++++++ sections= "+sections[g]);
      }

  // ExecutorService threadPool = Executors.newFixedThreadPool(nrOfProcessors);

      Object[] task = new Object[nrOfProcessors];

      for(int z = 0; z < nrOfProcessors; z++){
         task[z]  = (FutureTask<PartialResult>) threadPool.submit(new PartialProcessing(sections[z], sections[z+1] - 1, input, k, z));
         Log.e(TAG, "++++++++++ task"+z+"= "+task[z].toString()); 
      }

     PartialResult[] results = new PartialResult[nrOfProcessors];

     try{
          for(int t = 0; t < nrOfProcessors; t++){

              results[t] = ((FutureTask<PartialResult>) task[t]).get();

              results[t].fill(mArray);
          }

      }catch(Exception e){
          e.printStackTrace();
      }

 Log.v("yoRESULT", "height width = "+ input.getHeight()+" "+input.getWidth());
      Bitmap dst2 = Bitmap.createBitmap(mArray,input.getWidth(),input.getHeight(),input.getConfig());

    return dst2;


    }//end of barrel()




public class PartialResult {
       int startP;
       int endP;
       int[] storedValues;

       public PartialResult(int startp, int endp, Bitmap input){

           this.startP = startp;
           this.endP = endp;
           this.storedValues = new int[input.getWidth()*input.getHeight()];


       }

       public void addValue(int p, int result) {
             storedValues[p] = result;

       }

       public void fill(int[] mArray) {

           Log.v("yo09", startP + " " + endP + " " + input.getWidth());
           //yoko for (int p = startP; p < endP; p++){
       for (int p = startP; p < endP+1; p++){
               //for(int b=0;b<radius;b++,x++)
              for(int b=0;b<input.getWidth();b++,x++) {
                  mArray[x] = storedValues[x];
                  if (b == 0) Log.v("yoyoyo", p+" + " + storedValues[x]);
              }
          } 
          Log.e("yoFill", " ++++++++++ radius x = "+radius+" "+x);
   }

       }//end of partialResult




public class PartialProcessing implements Callable<PartialResult> {
    int startJ;
    int endJ;
    int mID;


    private int[] scalar;
    private float xscale;
    private float yscale;
    private float xshift;
    private float yshift;
    private float thresh = 1;
    private int [] s1;
    private int [] s2;
    private int [] s3;
    private int [] s4;
    private int [] s;
    private Bitmap input;
    private float k;



    public PartialProcessing(int startj, int endj, Bitmap input, float k, int mID) {

        this.startJ = startj;
        this.endJ = endj;
        this.input = input;
        this.k = k;
        this.mID = mID;

        s = new int[4];
        scalar = new int[4];
        s1 = new int[4];
        s2 = new int[4];
        s3 = new int[4];
        s4 = new int[4];

    }

    int [] getARGB(Bitmap buf,int x, int y){

        int rgb = buf.getPixel(y, x); // 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 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);
        }
      }


      //void sampleImage(Bitmap mArray, float idx0, float idx1)
    int [] sampleImage(Bitmap mArray2, float idx0, float idx1)
      {

         // s = new int [4];
        if(idx0<0 || idx1<0 || idx0>(mArray2.getHeight()-1) || idx1>(mArray2.getWidth()-1)){
          s[0]=0;
          s[1]=0;
          s[2]=0;
          s[3]=0;
          return s;// yoko
        }

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



    s1 = getARGB(mArray2,(int)idx0_fl,(int)idx1_fl);
    s2 = getARGB(mArray2,(int)idx0_fl,(int)idx1_cl);
    s3 = getARGB(mArray2,(int)idx0_cl,(int)idx1_cl);
    s4 = getARGB(mArray2,(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));

          return s;

      }



    @Override
    public PartialResult call() {

         PartialResult partialResult = new PartialResult(startJ, endJ,input);

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



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



          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;


        // yoko int p = startJ*radius;
        int p = startJ*width;//yoko
        int origPixel = 0;
        int color = 0;
        int i;

    Log.v("yokoIJ","PartialResult startJ endJ "+startJ+"  "+endJ);
        //yoko for (int j = startJ; j <  endJ; j++){
        for (int j = startJ; j <  endJ+1; j++){
            for ( i = 0; i < width; i++, p++){
    s = new int [4];//yoko added

    origPixel = input.getPixel(i,j);

    float x = getRadialX((float)j,(float)i,centerX,centerY,k);
    float y = getRadialY((float)j,(float)i,centerX,centerY,k);
    //sampleImage(input,x,y); //yoko
    s= sampleImage(input,x,y);

    color = (0xff<<24)|((s[1]&0x0ff)<<16)|((s[2]&0x0ff)<<8)|(s[3]&0x0ff);
    //Log.e(TAG, "radius = "+radius);

     //Not understand why it is not radius but radius/2
         //yoko if(((i-centerX)*(i-centerX) + (j-centerY)*(j-centerY)) <= radius*(radius/4)){
    if(((i-centerX)*(i-centerX) + (j-centerY)*(j-centerY)) <= radius*radius){
                //yo if(j%10 == 1 && i%10 == 1)
                    //yo Log.v("yoJI", mID+" "+j + " " + i );
        partialResult.addValue(p, color);
    }else{
        partialResult.addValue(p, origPixel);
        }

            }//end of inner for

    }//end of outer for

        return partialResult;
}//end of call
}// end of partialprocessing
}//end of MultiProcesorFilter

// 2. Filters.java:

class Filters{
float xscale;
float yscale;
float xshift;
float yshift;
int [] s;
private static String TAG = "Filters";
public Filters(){
    Log.e(TAG, "***********inside constructor");
}

public Bitmap barrel (Bitmap input, float k, boolean check, int Range){
    Log.e(TAG, "***********inside barrel method : hasAlpha = ");
    float centerX=input.getWidth()/2; //center of distortion
    float centerY=input.getHeight()/2;

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

//yoko        Log.v("yoQQ", width+" "+height+" "+centerX+" "+centerY);
    if(check)return input;

    Bitmap dst = Bitmap.createBitmap(width, height,input.getConfig() ); //output pic
    Log.e(TAG, "***********dst bitmap created ");
      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;
      Log.e(TAG, "***********about to loop through bm");
  Log.v("yoQQ2", xscale + " " + yscale);
  //if(check==1)return input;//yoko
      /*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.setPixel(i, j, color);

          }
        }*/

      int origPixel; // the pixel in orig image
      int i=0,j=0;
      for(j=0;j<dst.getHeight();j++){
          for(i=0;i<dst.getWidth();i++){
            s = new int [4];//yoko added
             origPixel= input.getPixel(i,j);
            float x = getRadialX((float)i,(float)j,centerX,centerY,k);
            float y = getRadialY((float)i,(float)j,centerX,centerY,k);
            //yoko sampleImage(input,x,y);
            s = sampleImage(input,x,y);
            //yoko int color = ((s[1]&0x0ff)<<16)|((s[2]&0x0ff)<<8)|(s[3]&0x0ff);
            int color = (0xff<<24)|((s[1]&0xff)<<16)|((s[2]&0xff)<<8)|(s[3]&0xff);
            //Log.v("yoQQ3", j + " " + i + " : "+dst.getHeight()+" "+dst.getWidth());


    // check whether a pixel is within the circle bounds of 150

            if( Math.sqrt( Math.pow(i - centerX, 2) + ( Math.pow(j - centerY, 2) ) ) <= Range ){
        dst.setPixel(i, j, color);
                //if(j%10 == 1 && i%10 == 1)
                //    Log.v("yoJI", j + " " + i );
            }else{
                dst.setPixel(i,j,origPixel);
            }
          }
        }
    Log.v("yoDONE", "========  Loop End ======== "+j+" "+i+" : " + dst.getHeight()+" "+dst.getWidth());
    return dst;
}//barrel

//    void sampleImage(Bitmap arr, float idx0, float idx1) // yoko
int[] sampleImage(Bitmap 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 s;
  }

  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));
  return s;///yoko added to make return the result value
}//sampleImage

int [] getARGB(Bitmap buf,int x, int y){
    int rgb = buf.getPixel(y, x); // 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;
}//getARGB

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

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

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);
  }
}//calc_shift
}

そして //3 MainActivity.java、最上位クラス。

public class MainActivity extends Activity {

ImageView iv1=null;
ImageView iv2=null;
Button bT, bB, b0;
Bitmap bitmap1, bitmap2, bitmapSP;
Boolean view1 = true;
private static final String TAG = "*********jjil";
public static int mH,mW,RADIUS;

@Override 
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    requestWindowFeature(Window.FEATURE_NO_TITLE);
    getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
            WindowManager.LayoutParams.FLAG_FULLSCREEN);

    setContentView(R.layout.activity_main);

    Resources res = this.getResources();
    //bitmap1 = BitmapFactory.decodeResource(res, R.drawable.checkerboard);
    bitmap1 = BitmapFactory.decodeResource(res, R.drawable.checkerboardback);
    mH=bitmap1.getHeight();
    mW=bitmap1.getWidth();
    RADIUS = mH/3;

    bT = (Button)findViewById(R.id.buttontoggle);
    bT.setOnClickListener(onClickToggleView);
    bB = (Button)findViewById(R.id.buttonbarrel);
    bB.setOnClickListener(onClickToggleView);
    b0 = (Button)findViewById(R.id.button0);
    b0.setOnClickListener(onClickToggleView);

    iv1=(ImageView)findViewById(R.id.touchview1);
    iv1.setImageBitmap(bitmap1);
    iv1.setVisibility(View.VISIBLE);


}//end of oncreate

public View.OnClickListener onClickToggleView = new View.OnClickListener() {
    public void onClick(View v) {
        if (v == bT) {

    /// fromhere
            new AsyncTask<Void, Void, String>() {
                com.example.owner.opengl2.Filters mFilers = new com.example.owner.opengl2.Filters();
                TextView tx = (TextView)findViewById(R.id.mStatus);
                Bitmap bitmapSP;long start,end;

                protected void onPreExecute() {
                    start = System.nanoTime();
                    iv1.setImageBitmap(bitmap1);
                    tx.setText("- Running -");
                }

                protected String doInBackground(Void... params) {
                     bitmapSP = mFilers.barrel(bitmap1,(float)0.00005,false,RADIUS);
                    return "message";
                }

                protected void onPostExecute(String msg) {
                    end = System.nanoTime();
                    long elapsedTime = end - start;
                    long seconds = elapsedTime / 1000000;

                    iv1.setImageBitmap(bitmapSP);
                    tx.setText("- READY : ElapsedTime(ms) = "+seconds);
                    // Post Code
                    // Use `msg` in code
                }
            }.execute();
    ///upto here



        } else if (v == bB){

    /// fromhere
            new AsyncTask<Void, Void, String>() {
                com.example.owner.opengl2.MultiRuntimeProcessorFilter mFilers = new com.example.owner.opengl2.MultiRuntimeProcessorFilter();
                TextView tx = (TextView)findViewById(R.id.mStatus);
                Bitmap bitmapSP;long start,end;

                protected void onPreExecute() {
                    start = System.nanoTime();
                    iv1.setImageBitmap(bitmap1);
                    tx.setText("- Running -");
                }

                protected String doInBackground(Void... params) {
                    bitmapSP = mFilers.barrel(bitmap1,(float)0.00005,RADIUS);
                    return "message";
                }

                protected void onPostExecute(String msg) {
                    end = System.nanoTime();
                    long elapsedTime = end - start;
                    //double seconds = (double)elapsedTime / 1000000000.0;
                    long seconds = elapsedTime / 1000000;
                    iv1.setImageBitmap(bitmapSP);
                    tx.setText("- READY : ElapsedTime(ms) = "+seconds);
                    // Post Code
                    // Use `msg` in code
                }
            }.execute();


        } else if (v == b0){
            new AsyncTask<Void, Void, String>() {
                protected String doInBackground(Void... Unused) {
                    return "OK";
                }
                protected void onPostExecute(String message) {
                    Log.v("YO", "---------------------------------");
                    Log.v("YO", "----------ORIGINAL SHAPE-------- "+message);
                    Log.v("YO", "---------------------------------");
                    iv1.setImageBitmap(bitmap1);

                    TextView tx = (TextView)findViewById(R.id.mStatus);
                    tx.setText("- READY : w h RADIUS = "+mW+" "+mH+" "+RADIUS);
                }
            }.execute();

        }
        ///upto here

    }
};

}

ここに XML ファイル //4 activity_main.xml があります

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent"
android:layout_height="match_parent" android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
android:orientation="vertical"
android:paddingBottom="@dimen/activity_vertical_margin" tools:context=".MainActivity">

<LinearLayout
    android:id="@+id/buttons"
    android:layout_centerHorizontal="true"
    android:layout_alignParentTop="true"
    android:orientation="horizontal"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content">

    <Button
        android:id="@+id/buttontoggle"
        android:text="Barrel 1P"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />

    <Button
    android:id="@+id/buttonbarrel"
    android:text="Barrele NP"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content" />

    <Button
        android:id="@+id/button0"
        android:text="ORIGINAL"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />


</LinearLayout>
<TextView
    android:id="@+id/mStatus"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text=" - Ready - "
    android:textAppearance="?android:attr/textAppearanceSmall"
    android:layout_below="@+id/buttons"
    android:layout_centerHorizontal="true"
    />

<ImageView
    android:id="@+id/touchview1"
    android:layout_below="@+id/mStatus"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:layout_centerHorizontal="true"
     />

<!--ImageView
    android:id="@+id/touchview2"
    android:layout_below="@+id/touchview1"
    android:layout_alignParentBottom="true"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:layout_centerHorizontal="true" /-->

于 2015-08-21T06:01:34.163 に答える
0

この歪みを合成画像に適用したいですか、それともビデオカメラなどに適用したいですか?

OpenCvでは、カメラのキャリブレーションを行うことができるはずです(組み込み関数、Zhangのアルゴリズムを使用)..

OpenGL では、これを参照してください。

よろしく

于 2009-12-18T10:04:16.917 に答える