Camera.FaceDetectionListener无法正常工作

时间:2013-12-26 12:58:08

标签: java android android-camera

我正在使用带有ICECREAMSANDWICH版本的Android手机。在那,我正在检查面部检测行为。另外,请参阅谷歌上提供的代码。

在使用我的手机int getMaxNumDetectedFaces ()进行调试期间,会返回3。所以我的手机支持这个。

然后以下代码无效。

public void onFaceDetection(Face[] faces, Camera face_camera1) {
    // TODO Auto-generated method stub
            if(faces.length>0)
            {
                Log.d("FaceDetection","face detected:" +faces.length + "Face 1 location X:"+faces[0].rect.centerX()+"Y:"+faces[0].rect.centerY());
            }
        }

在这个faces.length重新调整为零时告诉一些建议来解决这个错误。

1 个答案:

答案 0 :(得分:1)

前段时间我曾与FaceDetection合作过。当我正在研究onFaceDetection对我不起作用时,我找到了另一种工作方式。

我使用PreviewCallback,此方法采用每个帧,您可以使用它来识别面部。这里唯一的问题是格式,默认格式是NV21,您可以通过setPreviewFormat(int)更改它,但这对我也不起作用,所以,我不得不进行de转换以获得一个返回的Bitmap类型FaceDetector。这是我的代码:

public PreviewCallback mPreviewCallback = new PreviewCallback(){
@Override
public void onPreviewFrame(byte[] data, Camera camera) {

  Camera.Size size = camera.getParameters().getPreviewSize();
   Bitmap mfoto_imm = this.getBitmapFromNV21(data, size.width, size.height, true);  //here I get the Bitmap from getBitmapFromNV21 that is the conversion method    
    Bitmap mfoto= mfoto_imm.copy(Bitmap.Config.RGB_565, true); 
    imagen.setImageBitmap(mfoto);
    int alto= mfoto.getHeight();
    int ancho= mfoto.getWidth();
    int count;

   canvas= new Canvas(mfoto);
       dibujo.setColor(Color.GREEN);
   dibujo.setAntiAlias(true);
   dibujo.setStrokeWidth(8);
   canvas.drawBitmap(mfoto, matrix, dibujo);


    FaceDetector mface= new FaceDetector(ancho,alto,1);
    FaceDetector.Face [] face= new FaceDetector.Face[1];
    count = mface.findFaces(mfoto, face);


     PointF midpoint = new PointF();
     int fpx = 0;
         int fpy = 0;

     if (count > 0) {

face[count-1].getMidPoint(midpoint); // you have to take the last one less 1
         fpx= (int)midpoint.x;    // middle pint of  the face in x.
         fpy= (int)midpoint.y;    // middle point of the face in y.

     }

           canvas.drawCircle(fpx, fpy, 10, dibujo); // here I draw a circle on the middle of the face
     imagen.invalidate();

} }

以下是转换方法。

public Bitmap getBitmapFromNV21(byte[] data, int width, int height, boolean rotated) {

      Bitmap bitmap = null;
      int[] pixels = new int[width * height];

      // Conver the  array 
      this.yuv2rgb(pixels, data, width, height, rotated);


      if(rotated)
      {
        bitmap = Bitmap.createBitmap(pixels, height, width, Bitmap.Config.RGB_565);
      }
      else
      {
        bitmap = Bitmap.createBitmap(pixels, width, height, Bitmap.Config.RGB_565);
      }

      return bitmap;
    }


public void yuv2rgb(int[] out, byte[] in, int width, int height, boolean rotated) 
           throws NullPointerException, IllegalArgumentException 
         { 
          final int size = width * height; 


          if(out == null) throw new NullPointerException("buffer 'out' == null"); 
          if(out.length < size) throw new IllegalArgumentException("buffer 'out' length < " + size); 
          if(in == null) throw new NullPointerException("buffer 'in' == null"); 
          if(in.length < (size * 3 / 2)) throw new IllegalArgumentException("buffer 'in' length != " + in.length + " < " + (size * 3/ 2)); 

          // YCrCb
          int Y, Cr = 0, Cb = 0;


          int Rn = 0, Gn = 0, Bn = 0;
          for(int j = 0, pixPtr = 0, cOff0 = size - width; j < height; j++) { 
           if((j & 0x1) == 0)
            cOff0 += width;
           int pixPos = height - 1 - j; 
           for(int i = 0, cOff = cOff0; i < width; i++, cOff++, pixPtr++, pixPos += height) { 

            // Get Y
            Y = 0xff & in[pixPtr]; // 0xff es por el signo

            // Get Cr y Cb
            if((pixPtr & 0x1) == 0) { 
             Cr = in[cOff]; 
             if(Cr < 0) Cr += 127; else Cr -= 128;
             Cb = in[cOff + 1]; 
             if(Cb < 0) Cb += 127; else Cb -= 128; 

             Bn = Cb + (Cb >> 1) + (Cb >> 2) + (Cb >> 6);
             Gn = - (Cb >> 2) + (Cb >> 4) + (Cb >> 5) - (Cr >> 1) + (Cr >> 3) + (Cr >> 4) + (Cr >> 5);
             Rn = Cr + (Cr >> 2) + (Cr >> 3) + (Cr >> 5);
            } 


            int R = Y + Rn; 
            if(R < 0) R = 0; else if(R > 255) R = 255; 
            int B = Y + Bn; 
            if(B < 0) B = 0; else if(B > 255) B = 255; 
            int G = Y + Gn; 
            if(G < 0) G = 0; else if(G > 255) G = 255; //At this point the code could apply some filter From the separate components of the image.For example, they could swap 2 components or remove one

            int rgb = 0xff000000 | (R << 16) | (G << 8) | B; //Depending on the option the output buffer is filled or not applying the transformation
            if(rotated)
             out[pixPos] = rgb; 
            else
             out[pixPtr] = rgb;
           } 
          } 
         }
};

某些设备中的setPreviewFormat(int)不起作用,但也许您可以尝试创建Bitmap而不使用转换。 我希望这能帮到你。

相关问题