浏览图像和人脸检测

3
我遇到了一些关于检测上传图片中人脸的问题。我知道问题在于我不知道如何将正在测试的人脸检测代码应用于导入的图片上。我正在测试的示例代码是针对本地存储的图像编写的。我相信我已经接近成功,但你能帮我吗?
首先,我创建了一个图库方法。
    protected void gallery() {
    Intent intent = new Intent();
    intent.setType("image/*");
    intent.setAction("android.intent.action.GET_CONTENT");
    startActivityForResult(Intent.createChooser(intent, "Choose An Image"), 1);         
}

我还在学习意图等相关知识,但据我所知,我需要使用意图来使用Android的图库,并且因为我设置了获取内容的setAction,我也使用意图将信息传递给它。 有了这个前提,我试图将意图中的信息传递到一个URI中。 接下来是我的操作。

protected void onActivityResult(int requestCode, int resultCode, Intent intent) {
    super.onActivityResult(requestCode, resultCode, intent);
    if(requestCode == 1 && resultCode == RESULT_OK)
    {
        Uri uri = intent.getData();
        try {
            InputStream is = getContentResolver().openInputStream(uri);
            Bitmap bitmap = BitmapFactory.decodeStream(is);
            ImageView image = (ImageView)findViewById(R.id.img_view);
            image.setImageBitmap(bitmap);

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

对我来说,这里有些令人困惑的地方。我猜InputStream包含了图片信息?我尝试在同一try-catch中应用面部检测代码。我想在image.setImageBitmap(bitmap)完成后应用面部检测。以下是面部检测代码。

protected void onActivityResult(int requestCode, int resultCode, Intent intent) {
    super.onActivityResult(requestCode, resultCode, intent);
    if(requestCode == 1 && resultCode == RESULT_OK)
    {
        Uri uri = intent.getData();
        try {
            InputStream is = getContentResolver().openInputStream(uri);
            Bitmap bitmap = BitmapFactory.decodeStream(is);
            ImageView image = (ImageView)findViewById(R.id.image_view);
            image.setImageBitmap(bitmap);

            BitmapFactory.Options options = new BitmapFactory.Options();
            options.inPreferredConfig=Bitmap.Config.RGB_565;
            bitmap = BitmapFactory.decodeResource(getResources(), R.id.img_view, options);

            imageWidth = bitmap.getWidth();
            imageHeight = bitmap.getHeight();
            detectedFaces = new FaceDetector.Face[NUM_FACES];
            faceDetector= new FaceDetector(imageWidth, imageHeight, NUM_FACES);
            NUM_FACE_DETECTED = faceDetector.findFaces(bitmap, detectedFaces);
            mIL.invalidate();
        } catch (Exception e) {
            e.printStackTrace();
        }   
    }
}

我不知道如何更改“mFaceBitmap = BitmapFactory.decodeResource(getResources(),R.drawable.smilingfaces,options);”,它用于本地图片,以适应我认为存储在InputStream中的图像(还是吗?所选图像在哪里?)我想到的办法是调整imageView布局,因为图像在布局中。我不明白所有这些如何传输和协同工作。无论如何,这个代码片段应该检测人脸。然后onDraw()绘制出检测到的面部周围的正方形。我不确定放在哪里,但我将其放在了onActivityResult()之外。

protected void onDraw(Canvas canvas) {

    Paint myPaint = new Paint();
    myPaint.setColor(Color.RED);
    myPaint.setStyle(Paint.Style.STROKE);
    myPaint.setStrokeWidth(3);
    myPaint.setDither(true);

    for (int count = 0; count < NUM_FACE_DETECTED; count++) {
        Face face = detectedFaces[count];
        PointF midPoint = new PointF();
        face.getMidPoint(midPoint);

        eyeDistance = face.eyesDistance();
        canvas.drawRect(midPoint.x-eyeDistance, midPoint.y-eyeDistance, midPoint.x+eyeDistance, midPoint.y+eyeDistance, myPaint);   
    }
}

任何建议?我离让它工作非常接近!

我发现了一件事。我的onDraw没有被调用,所以我加入了invalidate(); 此外,我有一个想法。由于我正在imageView中显示选定的图像,因此可以使用bitmap = BitmapFactory.decodeResource(getResources(), R.id.image_view, options); 这些步骤好吗?但仍然没能解决问题。如果我不扩展ImageView,我不认为onDraw会起作用?或者这是否重要? - portfoliobuilder
1个回答

2

我明白您的意思。我将为您编写完整的代码,您只需跟着操作即可。

在此代码中,我将在布局中添加一个ImageView和两个类,一个是Activity类,另一个是ImageView类。

我将创建两个按钮,其中一个按钮用于从相册选择图像并显示它(用于人脸检测),而第二个按钮用于检测所选图像中的人脸。

首先是mainlayout.xml

<?xml version="1.0" encoding="utf-8"?>

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent" >

<com.simpleapps.facedetection.MyView
android:id="@+id/faceview"
android:layout_width="fill_parent" 
android:layout_height="fill_parent" 
/>

<LinearLayout 
android:orientation="horizontal"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_gravity="top">

<ImageView
    android:id="@+id/gallery"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_marginRight="10dp"
    android:layout_weight="1"
   android:background="@drawable/gallery" />

<ImageView
    android:id="@+id/detectf"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_marginRight="10dp"
    android:layout_weight="1"
   android:background="@drawable/detect" />


</LinearLayout>
</FrameLayout>

现在是活动类

MainActivity.java

 public class MainActivity extends Activity {

public MyView faceview;

public static Bitmap defaultBitmap;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
     requestWindowFeature(Window.FEATURE_NO_TITLE);
        getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
                WindowManager.LayoutParams.FLAG_FULLSCREEN);

        setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);

    setContentView(R.layout.activity_main);

     DisplayMetrics displaymetrics = new DisplayMetrics();
        getWindowManager().getDefaultDisplay().getMetrics(displaymetrics);
        screenHeight = displaymetrics.heightPixels;  
        screenWidth = displaymetrics.widthPixels; 

          faceview = (MyView)findViewById(R.id.faceview);

             myGallery = (LinearLayout)findViewById(R.id.mygallery);





          gallery=(ImageView)findViewById(R.id.gallery);
          detectf=(ImageView)findViewById(R.id.detectf);



          BitmapFactory.Options bitmapFatoryOptions=new BitmapFactory.Options();
            bitmapFatoryOptions.inPreferredConfig=Bitmap.Config.RGB_565;

          defaultBitmap=BitmapFactory.decodeResource(getResources(), R.drawable.face,bitmapFatoryOptions);

            faceview.setImage(defaultBitmap);

          gallery.setOnClickListener(new OnClickListener() {

                public void onClick(View v) {
                    // TODO Auto-generated method stub

                    Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
                    intent.setType("image/*");
                    startActivityForResult(intent, 0 );

                }
            });

          detectf.setOnClickListener(new OnClickListener() {

                public void onClick(View v) {
                    // TODO Auto-generated method stub


                    faceview.facedetect();

                }
            });

  }

 @Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {

    super.onActivityResult(requestCode, resultCode, data);

    if (resultCode == Activity.RESULT_OK) {

        if(requestCode==0){

        imageURI = data.getData(); 

        try {

             BitmapFactory.Options bitmapFatoryOptions=new BitmapFactory.Options();
            bitmapFatoryOptions.inPreferredConfig=Bitmap.Config.RGB_565;

            Bitmap b =  
                       BitmapFactory.decodeStream(getContentResolver().openInputStream(imageURI), null,  
                               bitmapFatoryOptions);


            faceview.myBitmap=b;


        } catch (FileNotFoundException e) {
//               TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {
//               TODO Auto-generated catch block  
            e.printStackTrace();
        }


        faceview.invalidate(); 

        }

        faceview.invalidate(); 
    } else {
        System.exit(0);
        Log.e("result", "BAD");
    }
 }
 }

现在是视图类。 我的视图.java。
public class MyView extends View {

private FaceDetector.Face[] detectedFaces;
private int NUMBER_OF_FACES=10;
private FaceDetector faceDetector;
private int NUMBER_OF_FACE_DETECTED;
private float eyeDistance;

public Paint myPaint;

public Bitmap resultBmp;

public Bitmap myBitmap,HairBitmap;

public PointF midPoint1;

public MyView(Context context, AttributeSet attrs) {
    super(context,attrs);
    // TODO Auto-generated constructor stub
    BitmapFactory.Options bitmapFatoryOptions=new BitmapFactory.Options();
    bitmapFatoryOptions.inPreferredConfig=Bitmap.Config.RGB_565;

}

public void setImage(Bitmap bitmap) {
    myBitmap = bitmap;

invalidate();
}


public void facedetect(){

     myPaint = new Paint();
        myPaint.setColor(Color.GREEN);
        myPaint.setStyle(Paint.Style.STROKE); 
        myPaint.setStrokeWidth(3);

    detectedFaces=new FaceDetector.Face[NUMBER_OF_FACES];
    faceDetector=new FaceDetector(resultBmp.getWidth(),resultBmp.getHeight(),NUMBER_OF_FACES);
    NUMBER_OF_FACE_DETECTED=faceDetector.findFaces(resultBmp, detectedFaces);

    System.out.println("faces detected are"+NUMBER_OF_FACE_DETECTED);

    Canvas facec=new Canvas();

    for(int count=0;count<NUMBER_OF_FACE_DETECTED;count++)
   {

    if(count==0){

         face1=detectedFaces[count];
        midPoint1=new PointF();
        face1.getMidPoint(midPoint1);

        eyeDistance=face1.eyesDistance();


    }

   }

    invalidate();

    if(NUMBER_OF_FACE_DETECTED==0){

    Toast.makeText(getContext(), "no faces detected", Toast.LENGTH_LONG).show(); 

    }else if(NUMBER_OF_FACE_DETECTED!=0){

        Toast.makeText(getContext(), "faces detected "+NUMBER_OF_FACE_DETECTED, Toast.LENGTH_LONG).show(); 

    }
}

protected void onDraw(Canvas canvas)
{

    if(myBitmap!=null)
    {



     w = myBitmap.getWidth();
     h = myBitmap.getHeight();
     resultBmp = null;

     int widthofBitMap  = MainActivity.screenWidth ;
     int heightofBitMap = widthofBitMap*h/w;

    resultBmp = Bitmap.createScaledBitmap(myBitmap, widthofBitMap, heightofBitMap, true);  
    canvas.drawBitmap(resultBmp, (MainActivity.screenWidth-widthofBitMap)/2,(MainActivity.screenHeight-heightofBitMap)/2, null);


    }

} 

@Override

  public boolean onTouchEvent(MotionEvent event) {
   // TODO Auto-generated method stub

   int action = event.getAction();



   switch(action){
   case MotionEvent.ACTION_MOVE:
    x = event.getX();
    y = event.getY();





    break;
   case MotionEvent.ACTION_DOWN:
    x = event.getX();
    y = event.getY();





    break;
   case MotionEvent.ACTION_UP:
   default:


}
   invalidate();
   return true;
  }


  }

我花了一些时间写这段代码,希望它能有所帮助。如果你遇到了错误,请随时提问。


谢谢!让我看看这个。希望这能解决我的问题。 - portfoliobuilder
这不是一个解决方案。你的代码示例存在许多问题。布局不存在,没有实现onClickListener,缺少变量和方法。我尝试提取一些可能有用的信息,但仍然无法解决问题。无论如何,还是谢谢。 - portfoliobuilder
是的,这就是我告诉你要问我的...我知道在从我的代码中提取并在这里发布时会出现错误。有什么问题吗?我可以帮助你。 - Sandeep R
我从我的应用程序中提取了它,所以你可能会发现很多错误。我会帮助你澄清它。告诉我哪些是错误的。 - Sandeep R
@SandeepR 你好,能否请您指导一下我如何在安卓10上实现这个功能。我想要将用户的面部与本地存储的文件/图像进行比较。 - Zala Janaksinh

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接