2

私は使っている:

  • アンドロイド 4.0.3
  • OpenCV 2.4.2
  • サムスンギャラクシー S2

顔検出の例 (opencv 2.4.2 から) は完全に機能しています。しかし今、私はカスタム レイアウトを作成し、実際に顔検出から抽出されたデータだけを使用してゲームを構築したいと考えています。必ずしも FdView サーフェスが画面全体を占めるとは限りません。

以下の変更を行いましたが、黒い画面しか表示されません。画面に何も表示されません。

fd.xml レイアウトを追加しました:

<LinearLayout 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:orientation="horizontal">

    <org.opencv.samples.fd.FdView android:id="@+id/FdView" 
        android:layout_width="640dp" 
        android:layout_height="480dp"
        android:visibility="visible"
        />

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textColor="#FF0000"
        android:text="hi"/>

FdActivity.java の baseLoaderCallback を変更しました。

    private BaseLoaderCallback  mOpenCVCallBack = new BaseLoaderCallback(this) {
    @Override
    public void onManagerConnected(int status) {
        switch (status) {
            case LoaderCallbackInterface.SUCCESS:
            {
                Log.i(TAG, "OpenCV loaded successfully");

                // Load native libs after OpenCV initialization
                System.loadLibrary("detection_based_tracker");

                //EXPERIMENT
                setContentView(R.layout.fd);
                FdView surface = (FdView) (findViewById(R.id.FdView));

                surface = mView;
                // Create and set View
                mView = new FdView(mAppContext);
                mView.setDetectorType(mDetectorType);
                mView.setMinFaceSize(0.2f);
                //setContentView(mView);


                // Check native OpenCV camera
                if( !mView.openCamera() ) {
                    AlertDialog ad = new AlertDialog.Builder(mAppContext).create();
                    ad.setCancelable(false); // This blocks the 'BACK' button
                    ad.setMessage("Fatal error: can't open camera!");
                    ad.setButton("OK", new DialogInterface.OnClickListener() {
                        public void onClick(DialogInterface dialog, int which) {
                        dialog.dismiss();
                        finish();
                        }
                    });
                    ad.show();
                }
            } break;
            default:
            {
                super.onManagerConnected(status);
            } break;
        }
    }
};

FdView.java に追加されたコンストラクター:

    public FdView(Context context, AttributeSet attrs, int defStyle) {
    super(context, attrs, defStyle);
    // TODO Auto-generated constructor stub
}

public FdView(Context context, AttributeSet attrs) {
    super(context, attrs);
    // TODO Auto-generated constructor stub
}

SampleCvViewBase.java に追加されたコンストラクター:

    public SampleCvViewBase(Context context, AttributeSet attrs, int defStyle) {
    super(context, attrs, defStyle);
    // TODO Auto-generated constructor stub
}

public SampleCvViewBase(Context context, AttributeSet attrs) {
    super(context, attrs);
    // TODO Auto-generated constructor stub
}
4

4 に答える 4

1

私はまったく同じ問題を抱えています。また、それを理解しようとしています。SurfaceView画面全体を占有しない画像を表示しようとしています。それで、カメラ ハンドラー クラスを使用して別のクラスにリンクすることはできないと読みSurfaceViewました。だからすべてを1つにぶつけた。

そのため、現時点ではカメラを に表示し、フレーム データを変数SurfaceViewにコピーしています。基本的には、(マルチスレッド、Run()、関数で) 処理されたmFrameものを取得するのに苦労し、 .mFrameSurfaceView

これは私が持っているコードです。役立つと思われる場合: (私のコードも進行中の作業であるため、書式設定を許してください)

package org.opencv.samples.tutorial3;

import java.io.IOException;
import java.util.List;

import org.opencv.android.BaseLoaderCallback;
import org.opencv.android.LoaderCallbackInterface;
import org.opencv.android.OpenCVLoader;

import android.app.Activity;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.ImageFormat;
import android.graphics.Paint;
import android.graphics.Rect;
import android.graphics.RectF;
import android.hardware.Camera;
import android.hardware.Camera.PreviewCallback;
import android.os.Bundle;
import android.util.Log;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.Window;
import android.widget.TextView;

public class Sample3Native extends Activity implements SurfaceHolder.Callback,Runnable{


    //Camera variables
    private Camera              cam;
    private boolean             previewing = false;
    private SurfaceHolder       mHolder;
    private SurfaceView         mViewer;
    private int                 mFrameWidth;
    private int                 mFrameHeight;
    private byte[]              mFrame;
    private boolean             mThreadRun;
    private byte[]              mBuffer;
    Sample3View viewclass;
    TextView text;
    int value = 0;
    //==========

    int framecount = 0;

    private BaseLoaderCallback  mOpenCVCallBack = new BaseLoaderCallback(this) {
        @Override
        public void onManagerConnected(int status) {
            switch (status) {
                case LoaderCallbackInterface.SUCCESS:
                {

                    // Load native library after(!) OpenCV initialization
                    System.loadLibrary("native_sample");

                    //constructor for viewclass that works on frames
                    viewclass = new Sample3View();

                    //setContentView(mView);
                    //OpenCam();
                    //setContentView(R.layout.main);

                    // Create and set View
                    CameraConstruct();
                    Camopen();

                } break;
                default:
                {
                    super.onManagerConnected(status);
                } break;
            }
        }
    };

    public Sample3Native()
    {}

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

        setContentView(R.layout.main);

        OpenCVLoader.initAsync(OpenCVLoader.OPENCV_VERSION_2_4_2, this, mOpenCVCallBack);
    }

    //Camera construction
    public void CameraConstruct()
    {
        mViewer = (SurfaceView)findViewById(R.id.camera_view);
        text = (TextView)findViewById(R.id.text);
        mHolder = mViewer.getHolder();
        mHolder.addCallback(this);
        mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
    }


    //calls camera screen setup when screen surface changes
    public void surfaceChanged(SurfaceHolder holder, int format, int width,int height) 
    {
        CamStartDisplay();  
    }

    public void Camclose()
    {
        if(cam != null && previewing)
        {
            cam.setPreviewCallback(null);
            cam.stopPreview();
            cam.release();
            cam = null;

            previewing = false;
        }

        mThreadRun = false;
        viewclass.PreviewStopped();
    }

    //only open camera, and get frame data
    public void Camopen()
    {
        if(!previewing){
            cam = Camera.open();
            //rotate display
            cam.setDisplayOrientation(90);
            if (cam != null)
            {
                //copy viewed frame
                cam.setPreviewCallbackWithBuffer(new PreviewCallback() 
                {

                    public void onPreviewFrame(byte[] data, Camera camera) 
                    {
                        synchronized (this) 
                        {
                            System.arraycopy(data, 0, mFrame, 0, data.length);

                            this.notify(); 
                        }
                        //text.setText(Integer.toString(value++));
                        camera.addCallbackBuffer(mBuffer);
                    }
                });

            }

        }//if not previewing
    }

    //start preview
    public void CamStartDisplay()
    {
        synchronized (this) 
        {
            if(cam != null)
            {
                //stop previewing till after settings is changed
                if(previewing == true)
                {
                    cam.stopPreview();
                    previewing = false;
                }

                Camera.Parameters p = cam.getParameters();
                for(Camera.Size s : p.getSupportedPreviewSizes())
                {
                    p.setPreviewSize(s.width, s.height);
                    mFrameWidth = s.width;
                    mFrameHeight = s.height;
                    break;
                }

                p.setPreviewSize(mFrameWidth, mFrameHeight);

                List<String> FocusModes = p.getSupportedFocusModes();
                if (FocusModes.contains(Camera.Parameters.FOCUS_MODE_CONTINUOUS_VIDEO))
                {
                    p.setFocusMode(Camera.Parameters.FOCUS_MODE_CONTINUOUS_VIDEO);
                }
                cam.setParameters(p);

                //set the width and height for processing
                viewclass.setFrame(mFrameWidth, mFrameHeight);

                int size = mFrameWidth*mFrameHeight;
                size  = size * ImageFormat.getBitsPerPixel(p.getPreviewFormat()) / 8;
                mBuffer = new byte[size];
                mFrame = new byte [size];
                cam.addCallbackBuffer(mBuffer);

                viewclass.PreviewStarted(mFrameWidth, mFrameHeight);

                //start display streaming
                try 
                {
                    //cam.setPreviewDisplay(null);
                    cam.setPreviewDisplay(mHolder);
                    cam.startPreview();
                    previewing = true;
                } 
                catch (IOException e) 
                {
                    e.printStackTrace();
                }

            }//end of if cam != null
        }//synchronising
    }

    //thread gets started when the screen surface is created
    public void surfaceCreated(SurfaceHolder holder) {
        //Camopen();
        //CamStartDisplay();
        (new Thread(this)).start(); 
    }

    //called when the screen surface is stopped
    public void surfaceDestroyed(SurfaceHolder holder) 
    {
        Camclose();
    }

    //this is function that is run by thread
    public void run() 
    {

        mThreadRun = true;
        while (mThreadRun) 
        {
            //text.setText(Integer.toString(value++));
            Bitmap bmp = null;

            synchronized (this) 
            {
                try 
                {
                    this.wait();

                    bmp = viewclass.processFrame(mFrame);
                } 
                catch (InterruptedException e) {}
            }

            if (bmp != null) 
            {
                Canvas canvas = mHolder.lockCanvas();

                if (canvas != null) 
                {
                    canvas.drawBitmap(bmp, (canvas.getWidth() - mFrameWidth) / 2, (canvas.getHeight() - mFrameHeight) / 2, null);
                    mHolder.unlockCanvasAndPost(canvas);
                }
            }//if bmp != null
        }// while thread in run
    }


}//end class

Sample3Viewこのクラスで使用されているように、次のprocessFrameような関数が含まれています。

package org.opencv.samples.tutorial3;

import android.content.Context;
import android.graphics.Bitmap;
import android.widget.TextView;

class Sample3View {

    private int mFrameSize;
    private Bitmap mBitmap;
    private int[] mRGBA;

    private int frameWidth;
    private int frameHeight;
    private int count = 0;

    Sample3Native samp;

    //constructor
    public Sample3View() 
    {
    }

    public void setFrame(int width,int height)
    {
        frameWidth = width;
        frameHeight = height;
    }

    public void PreviewStarted(int previewWidtd, int previewHeight) {
        mFrameSize = previewWidtd * previewHeight;
        mRGBA = new int[mFrameSize];
        mBitmap = Bitmap.createBitmap(previewWidtd, previewHeight, Bitmap.Config.ARGB_8888);
    }

    public void PreviewStopped() {
        if(mBitmap != null) {
            mBitmap.recycle();
            mBitmap = null;
        }
        mRGBA = null;   
    }

    public Bitmap processFrame(byte[] data) {
        int[] rgba = mRGBA;

        FindFeatures(frameWidth, frameHeight, data, rgba);

        Bitmap bmp = mBitmap; 
        bmp.setPixels(rgba, 0, frameWidth, 0, 0, frameWidth, frameHeight);


        //samp.setValue(count++);
        return bmp;
    }

    public native void FindFeatures(int width, int height, byte yuv[], int[] rgba);
}

ええ、これが役立つことを願っています。完全なソリューションが機能するようになったら、それも投稿します。また、最初に解決策を見つけたら投稿してください。楽しみ

于 2012-09-27T04:13:32.990 に答える
0

レイアウトを使用してカスタム ビューを作成したいという同じ問題に遭遇しました。OpenCV 2.4.2 はこの機能を提供していないようです。OpenCV 2.4.3には機能がありますが、そのチュートリアルにはそうは書かれていません(OpenCV2.4.2の古い例を使用しています)。その Android サンプルは、いくつかの洞察を提供します。最後に、OpenCV 2.4.9 documentationで指示を見つけました。

それが役に立てば幸い。

于 2012-12-31T23:13:59.433 に答える
0

はぁ、ひとつ方法がわかった。OpenCV ローダーとカスタム レイアウトを簡単に分離できます。

BaseLoaderCallback mOpenCVCallBack を定義します。

    private BaseLoaderCallback mOpenCVCallBack = new BaseLoaderCallback(this) {

    @Override
    public void onManagerConnected(int status) {
        switch (status) {
        case LoaderCallbackInterface.SUCCESS: {
            Log.i(TAG, "OpenCV loaded successfully");

            // Load native library after(!) OpenCV initialization
            System.loadLibrary("native_sample");    
        }
            break;
        default: {
            super.onManagerConnected(status);
        }
            break;
        }
    }
};

OnCreat で、カスタム レイアウトを構築し、OpenCv ローダーをロードします。

    public void onCreate(Bundle savedInstanceState) {
    Log.i(TAG, "onCreate");
    super.onCreate(savedInstanceState);
    requestWindowFeature(Window.FEATURE_NO_TITLE);

    // /////////////////////////////////////////////////////////////////////
    // // begin:
    // // Create and set View
    setContentView(R.layout.main);
    mView = (Sample3View) findViewById(R.id.sample3view);

    mcameraButton = (ImageView) findViewById(R.id.cameraButton);

    if (!OpenCVLoader.initAsync(OpenCVLoader.OPENCV_VERSION_2_4_2, this, mOpenCVCallBack)) {
        Log.e(TAG, "Cannot connect to OpenCV Manager");
    }

}

それだけ!私はそれをしました、そしてそれは非常にうまくいきました。

于 2013-01-06T03:38:09.750 に答える
0

(まだ)本当の答えではありませんが、opencv 2.4.2でカスタムレイアウトを作成しようとしました

私は2.4.0でこの完全に機能するソリューションを持っています.それが正しいことを覚えていれば、インストラクターを追加するだけで十分でした..しかし、2.4.2では機能しません

私はsmthgを理解しようとし、皆さんに知らせます.

于 2012-09-28T08:47:14.840 に答える