Face detection using OpenCV Java Android's camera onPreviewFrame()'s byte[] data does not work.

asked 2013-11-15 08:00:38 -0500

updated 2013-11-15 12:34:31 -0500

berak gravatar image

I am trying to used OpenCV java wrapper to detect faces in an app.

1) The app is using front-facing camera in potrait mode.

2) The preview is displayed inside a SurfaceView.

3) I am using Android's onPreviewFrame()'s byte[] data and changing it into OpenCV format to detect the faces using OpenCV.

4) I send the coordinates detected by mJavaDetector to a View class to be drawn on a instance of the drawingView surface.

When I start the application, there are no errors but no rectangle is drawn. The "Log.v(TAG, "Length of facesArray" + facesArray.length);" inside SurfaceChanged is also not displayed. Is it because the onPreviewFrame() is not called or a problem with my OpenCV implementation or other problems?

I have attached my codes below.

public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {

     /**if(previewing){
           //mCamera.stopFaceDetection();
           mCamera.stopPreview();
           previewing = false;
          }**/

          if (mCamera != null){
           try {
               mCamera.setPreviewDisplay(surfaceHolder);
               mCamera.startPreview();
               mCamera.setPreviewCallback(new PreviewCallback() {
                    public void onPreviewFrame(byte[] data, Camera mCamera) {
                        Log.d(TAG, "ON Preview frame");
                        int mAbsoluteFaceSize   = 0;


                        int width = surfaceView.getWidth();
                        int height = surfaceView.getHeight();
                        Mat img = new Mat(height, width, CvType.CV_8UC1);
                        Mat gray = new Mat(height, width, CvType.CV_8UC1);
                        img.put(0, 0, data);        

                        Imgproc.cvtColor(img, gray, Imgproc.COLOR_YUV420sp2GRAY);

                        MatOfRect faces = new MatOfRect();

                        if (mJavaDetector != null)
                            mJavaDetector.detectMultiScale(gray, faces, 1.1, 2, 2, // TODO: objdetect.CV_HAAR_SCALE_IMAGE
                                    new Size(mAbsoluteFaceSize, mAbsoluteFaceSize), new Size());

                        Rect[] facesArray = faces.toArray();

                        Log.v(TAG, "Length of facesArray" + facesArray.length);

                        if(facesArray != null){
                            drawingView.setHaveFace(true);
                        }

                        for (int i = 0; i < facesArray.length; i++){
                            double l = facesArray[i].tl().x;
                            double t = facesArray[i].tl().y;
                            double r = facesArray[i].br().x;
                            double b = facesArray[i].br().y;
                            drawingView.setCoordinates(l, t, r, b);
                        }

                    }
                    });

            /**prompt.setText(String.valueOf(
              "Max Face: " + mCamera.getParameters().getMaxNumDetectedFaces()));
              mCamera.startFaceDetection();
            previewing = true;**/
           } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
           }
          }
}

private class DrawingView extends View{

      boolean haveFace;
      Paint drawingPaint;
      float left;
      float top;
      float right;
      float bottom;

      public DrawingView(Context context) {
       super(context);
       haveFace = false;
       drawingPaint = new Paint();
       drawingPaint.setColor(Color.GREEN);
       drawingPaint.setStyle(Paint.Style.STROKE); 
       drawingPaint.setStrokeWidth(2);
      }

      public void setHaveFace(boolean h){
       haveFace = h;
      }

      public void setCoordinates(double l,double t, double r, double b){
          left = (float)l;
          top = (float)t;
          right = (float)r;
          bottom = (float)b;
      }
      @Override
      protected void onDraw(Canvas canvas) {

        if(haveFace){
            canvas.drawRect(
                       left, top, right, bottom,  
                       drawingPaint);
        }
        else{
            canvas.drawColor(Color.TRANSPARENT);
        }
      }
     }

My drawingView declaration in onCreate()

  drawingView = new DrawingView(this);
    LayoutParams layoutParamsDrawing 
     = new LayoutParams(LayoutParams.FILL_PARENT, 
       LayoutParams.FILL_PARENT);
    this.addContentView(drawingView, layoutParamsDrawing);
edit retag flag offensive close merge delete