4

我正在尝试使用面部检测进行面部交换类型的应用程序。直到现在我得到位图中检测到的面孔并在检测到的面孔上绘制椭圆形。但现在我需要使用椭圆内的面,这样我就可以交换两个面。是否可以。我需要一些关于这方面的建议。

我的活动课如下

public class FaceDetectionActivity extends Activity 
{


public MyView faceview;
public ImageView gallery;
private Uri imageURI;

/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) 
{
    super.onCreate(savedInstanceState);
    //setContentView(R.layout.main);
    setContentView(R.layout.main);

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

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

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

        }
    });


}


@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 {
            Bitmap b = android.provider.MediaStore.Images.Media.getBitmap(getContentResolver(), imageURI);

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


}

和我的视图类

public class MyView extends ImageViewTouchBase {

public RectF rectF;
public Bitmap myBitmap;
private int width, height;
private FaceDetector.Face[] detectedFaces;
private int NUMBER_OF_FACES=10;
private FaceDetector faceDetector;
private int NUMBER_OF_FACE_DETECTED;
private float eyeDistance;
Matrix mImageMatrix;

public MyView(Context context, AttributeSet attrs) 
{
    super(context, attrs);
    BitmapFactory.Options bitmapFatoryOptions=new BitmapFactory.Options();
    bitmapFatoryOptions.inPreferredConfig=Bitmap.Config.RGB_565;
    myBitmap=BitmapFactory.decodeResource(getResources(), R.drawable.familyportrait,bitmapFatoryOptions);
    width=myBitmap.getWidth();
    height=myBitmap.getHeight();
    detectedFaces=new FaceDetector.Face[NUMBER_OF_FACES];
    faceDetector=new FaceDetector(width,height,NUMBER_OF_FACES);
    NUMBER_OF_FACE_DETECTED=faceDetector.findFaces(myBitmap, detectedFaces);
}

@Override
protected void onDraw(Canvas canvas)
{
    if(myBitmap!=null)
    {


    canvas.drawBitmap(myBitmap, 0,0, null);

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

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

        eyeDistance=face.eyesDistance();

    float   left = midPoint.x - (float)(1.4 * eyeDistance);
    float   right = midPoint.x + (float)(1.4 * eyeDistance);
    float    top = midPoint.y - (float)(1.8 * eyeDistance);
    float    bottom = midPoint.y + (float)(1.8 * eyeDistance);

    Rect imageRect = new Rect(0, 0, width, height);
     rectF = new RectF();

    rectF.set(left,top,right,bottom);

    canvas.drawOval(rectF, myPaint);


    }
}

}

现在我想要选择椭圆内的内容。请给我一些想法。

4

2 回答 2

3

我刚刚想通了。我正在使用上面代码中的变量 Left、Right、Top 和 Bottom 创建另一个位图。然后我得到一个正方形的面图。我从正方形的位图面中提取圆形位图。就是这样。

于 2013-09-21T04:16:31.197 回答
1

试试这个代码:

public class MainActivity extends ProgressA {

    public static final String FACE_1 = "face_1";
    public static final String FACE_2 = "face_2";

    private ImageView mIvForDetect;
    private ImageView mIvForDetect2;
    private ImageView mIvForDetect3;
    private ImageView mIvForDetect4;
    //private Bitmap baseBTM;
    private Bitmap face1BTM;
    private Bitmap face2BTM;

    boolean face1Done = false;
    boolean face2Done = false;

    private FirebaseVisionFaceDetector detector;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Toolbar toolbar = findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);

        mIvForDetect = findViewById(R.id.iv_main_for_detect);
        mIvForDetect2 = findViewById(R.id.iv_main_for_detect2);
        mIvForDetect3 = findViewById(R.id.iv_main_for_detect3);
        mIvForDetect4 = findViewById(R.id.iv_main_for_detect4);
        //baseBTM = BitmapFactory.decodeResource(getResources(), R.drawable.paj);
        mIvForDetect.setImageBitmap(BitmapFactory.decodeResource(getResources(), R.drawable.jolie));
        mIvForDetect2.setImageBitmap(BitmapFactory.decodeResource(getResources(), R.drawable.pitt));

        detector = FirebaseVision.getInstance().getVisionFaceDetector(buildCloudVisionOptions());

        FloatingActionButton fab = findViewById(R.id.fab);
        fab.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                showProgressDialog();
                Thread thread = new Thread(new Runnable() {
                    @Override
                    public void run() {
                        detectFace(mIvForDetect, FACE_1, null);
                        detectFace(mIvForDetect2,FACE_2, null);
                    }
                });
                thread.start();
            }
        });
    }

    private void checkFaces() {
        if (face1Done && face2Done){
            swapFaces();
        }
    }

    private void swapFaces() {
        detectFace(mIvForDetect, FACE_1, face2BTM);
        detectFace(mIvForDetect2, FACE_2, face1BTM);
    }

    private void detectFace(final ImageView view, final String face, final Bitmap fakeFace) {

        final Bitmap baseBTM = ((BitmapDrawable) view.getDrawable()).getBitmap();
        FirebaseVisionImage image = FirebaseVisionImage.fromBitmap(baseBTM);
        detector.detectInImage(image)
                .addOnSuccessListener(new OnSuccessListener<List<FirebaseVisionFace>>() {
                    @Override
                    public void onSuccess(List<FirebaseVisionFace> faces) {
                        if (fakeFace != null){
                            setFakeFace(view, faces.get(0), baseBTM, fakeFace);
                            hideProgressDialog();
                        }else {
                            switch (face){
                                case FACE_1:
                                    face1BTM = createTrimmedBitmap(cutFaces(faces.get(0), baseBTM));
                                    mIvForDetect3.setImageBitmap(face1BTM);
                                    face1Done = true;
                                    checkFaces();
                                    break;
                                case FACE_2:
                                    face2BTM = createTrimmedBitmap(cutFaces(faces.get(0), baseBTM));
                                    mIvForDetect4.setImageBitmap(face2BTM);
                                    face2Done = true;
                                    checkFaces();
                                    break;
                            }
                        }
                    }
                })
                .addOnFailureListener(new OnFailureListener() {
                    @Override
                    public void onFailure(@NonNull Exception e) {
                        hideProgressDialog();
                        Toast.makeText(MainActivity.this, e.getMessage(), Toast.LENGTH_SHORT).show();
                    }
                });
    }

    public FirebaseVisionFaceDetectorOptions buildCloudVisionOptions() {
        return new FirebaseVisionFaceDetectorOptions.Builder()
                .setPerformanceMode(FirebaseVisionFaceDetectorOptions.ACCURATE)
                .setLandmarkMode(FirebaseVisionFaceDetectorOptions.ALL_LANDMARKS)
                .setClassificationMode(FirebaseVisionFaceDetectorOptions.ALL_CLASSIFICATIONS)
                .setPerformanceMode(FirebaseVisionFaceDetectorOptions.FAST)
                .build();
    }

    public static Bitmap createTrimmedBitmap(Bitmap bmp) {
        int imgHeight = bmp.getHeight();
        int imgWidth = bmp.getWidth();
        int smallX = 0, largeX = imgWidth, smallY = 0, largeY = imgHeight;
        int left = imgWidth, right = imgWidth, top = imgHeight, bottom = imgHeight;
        for (int i = 0; i < imgWidth; i++) {
            for (int j = 0; j < imgHeight; j++) {
                if (bmp.getPixel(i, j) != Color.TRANSPARENT) {
                    if ((i - smallX) < left) {
                        left = (i - smallX);
                    }
                    if ((largeX - i) < right) {
                        right = (largeX - i);
                    }
                    if ((j - smallY) < top) {
                        top = (j - smallY);
                    }
                    if ((largeY - j) < bottom) {
                        bottom = (largeY - j);
                    }
                }
            }
        }
        bmp = Bitmap.createBitmap(bmp, left, top, imgWidth - left - right, imgHeight - top - bottom);
        return bmp;
    }

    public Bitmap cutFaces(FirebaseVisionFace face, Bitmap baseBTM) {
        Bitmap tempBitmap = Bitmap.createBitmap(baseBTM.getWidth(), baseBTM.getHeight(), Bitmap.Config.RGB_565);
        Canvas tempCanvas = new Canvas(tempBitmap);
        tempCanvas.drawBitmap(baseBTM, 0, 0, null);
        int top = face.getBoundingBox().top;
        int left = Math.round(face.getLandmark(FirebaseVisionFaceLandmark.LEFT_EAR).getPosition().getX());
        int right = Math.round(face.getLandmark(FirebaseVisionFaceLandmark.RIGHT_EAR).getPosition().getX());
        int bottom = face.getBoundingBox().bottom;
        Bitmap output = Bitmap.createBitmap(tempBitmap.getWidth(), tempBitmap.getHeight(), Bitmap.Config.ARGB_8888);
        Canvas canvas = new Canvas(output);
        final Paint paint = new Paint();
        canvas.drawOval(left, top, right, bottom, paint);
        paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));
        canvas.drawBitmap(tempBitmap, new Matrix(), paint);
        return output;
    }

    public void setFakeFace(ImageView view, FirebaseVisionFace face, Bitmap baseBTM, Bitmap fakeFace) {

        Bitmap resultBitmap = Bitmap.createBitmap(baseBTM.getWidth(), baseBTM.getHeight(), baseBTM.getConfig());
        Canvas canvas = new Canvas(resultBitmap);
        final Paint paintSRC = new Paint();
        final Paint paintDST = new Paint();

        int top = face.getBoundingBox().top;
        int left = Math.round(face.getLandmark(FirebaseVisionFaceLandmark.LEFT_EAR).getPosition().getX());
        int right = Math.round(face.getLandmark(FirebaseVisionFaceLandmark.RIGHT_EAR).getPosition().getX());
        int bottom = face.getBoundingBox().bottom;
        int weight = right - left;
        int height = bottom - top;

        canvas.drawOval(left, top, right, bottom, paintSRC);
        paintSRC.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_OUT));
        paintDST.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_OVER));
        Matrix matrix = new Matrix();
        matrix.postScale(face.getLandmark(FirebaseVisionFaceLandmark.LEFT_EAR).getPosition().getX(), face.getBoundingBox().top);

        canvas.drawBitmap(baseBTM, 0, 0, null);
        canvas.drawBitmap(Bitmap.createScaledBitmap(fakeFace, weight, height, false), left, top, paintDST);
        view.setImageBitmap(resultBitmap);
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.menu_main, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle action bar item clicks here. The action bar will
        // automatically handle clicks on the Home/Up button, so long
        // as you specify a parent activity in AndroidManifest.xml.
        int id = item.getItemId();
        //noinspection SimplifiableIfStatement
        if (id == R.id.action_settings) {
            return true;
        }
        return super.onOptionsItemSelected(item);
    } }
于 2019-09-16T12:31:30.067 回答