【问题标题】:Android + OpenCV + Face detection + Custom LayoutAndroid + OpenCV + 人脸检测 + 自定义布局
【发布时间】:2012-07-14 21:17:03
【问题描述】:

我正在使用:

  • Android 4.0.3
  • OpenCV 2.4.2
  • 三星 Galaxy 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
}

【问题讨论】:

    标签: android opencv


    【解决方案1】:

    我也有同样的问题。也想弄清楚。我正在尝试在不占用整个屏幕的SurfaceView 上显示图像。我读到你不能有你的相机处理程序类并在不同的类中链接SurfaceView。所以把所有东西都粉碎了。

    所以,目前我在SurfaceView 上显示相机,并将帧数据复制到mFrame 变量。基本上只是努力处理mFrame(在多线程、Run()、函数中)并在SurfaceView 上显示结果。

    这是我的代码,如果您认为它会有所帮助:(请原谅格式化,因为我的代码也在进行中)

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

    是的,希望这会有所帮助。如果我得到完整的解决方案,我也会发布。如果你先得到解决方案,也请发布你的东西!享受

    【讨论】:

      【解决方案2】:

      抱歉,这不是一个真正的答案(还),但也尝试在 opencv 2.4.2 中进行自定义布局

      如果我没记错的话,我有这个完美的 2.4.0 解决方案,添加讲师就足够了.. 但它不适用于 2.4.2

      我会想办法让你们知道的。

      【讨论】:

        【解决方案3】:

        我遇到了同样的问题,我想使用布局创建自定义视图。 OpenCV 2.4.2 似乎没有提供这个功能。 OpenCV 2.4.3 有这个功能,但它的教程没有这么说(它使用了 OpenCV2.4.2 中的旧示例)。它的 Android 示例提供了一些见解。终于在OpenCV 2.4.9 documentation找到了指令。

        希望对你有帮助。

        【讨论】:

          【解决方案4】:

          哈,我想出了一个办法。您可以简单地将 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");
              }
          
          }
          

          就是这样! 我这样做了,效果很好。

          【讨论】:

          • 您好,我正在使用自定义相机来捕获图像并检查图像是否模糊或未使用 opencv,但它无法在自定义相机中工作。如果可能,请帮助我。提前致谢。
          猜你喜欢
          • 1970-01-01
          • 2012-02-04
          • 2013-05-24
          • 1970-01-01
          • 1970-01-01
          • 2014-01-31
          • 2012-04-15
          • 2017-08-30
          • 2013-09-24
          相关资源
          最近更新 更多