как правильно выровнять контур лица в firebase mlkit? - PullRequest
0 голосов
/ 18 декабря 2018

Я видел много примеров и пытался создать приложение для контурирования лица, и все работало как ожидалось, но по какой-то причине точки не выравнивались с фактическим лицом.

вот мой код активности

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    xmlns:app="http://schemas.android.com/apk/res-auto">

    <com.otaliastudios.cameraview.CameraView
        android:id="@+id/cvv"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:cameraFacing="front"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" >

    <com.kirtu.simpletexts.texts.OverlayView
        android:id="@+id/overlayView"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_alignParentStart="true"
        android:layout_alignParentTop="true"
        android:layout_alignParentBottom="true" />
    </com.otaliastudios.cameraview.CameraView>
</android.support.constraint.ConstraintLayout>

вот основной код активности

public class filter extends AppCompatActivity {
    int previewh,previeww;
    CameraView cv;
    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.filter);
        cv = findViewById(R.id.cvv);
        cv.setLifecycleOwner(this);
        cv.start();
        final OverlayView ov = findViewById(R.id.overlayView);
        View decorView = getWindow().getDecorView();
        int uiOptions = View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
                | View.SYSTEM_UI_FLAG_FULLSCREEN;
        decorView.setSystemUiVisibility(uiOptions);
        FirebaseVisionFaceDetectorOptions op =new FirebaseVisionFaceDetectorOptions.Builder()
                .setContourMode(FirebaseVisionFaceDetectorOptions.ALL_CONTOURS)
                .build();
        final FirebaseVisionFaceDetector detector= FirebaseVision.getInstance().getVisionFaceDetector(op);
        cv.addFrameProcessor(new FrameProcessor() {
            @Override
            public void process(@NonNull Frame frame) {
                if(frame.getSize() != null)
                {
                    int rotation = frame.getRotation()/ 90;
                    if(rotation/2 == 0)
                    {
                        previewh = cv.getPreviewSize().getHeight();
                        previeww = cv.getPreviewSize().getWidth();
                        //Log.d("texts", "process: "+cv.getPreviewSize().getWidth()+"  "+cv.getPreviewSize().getHeight());
                    }else
                    {
                        previewh = cv.getPreviewSize().getWidth();
                        previeww = cv.getPreviewSize().getHeight();
                        //Log.d("texts", "process: "+cv.getPreviewSize().getWidth()+"  "+cv.getPreviewSize().getHeight());
                    }
                    FirebaseVisionImageMetadata metadata = new FirebaseVisionImageMetadata.Builder()
                            .setFormat(FirebaseVisionImageMetadata.IMAGE_FORMAT_NV21)
                            .setWidth(frame.getSize().getWidth())
                            .setHeight(frame.getSize().getHeight())
                            .setRotation(rotation)
                            .build();
                    FirebaseVisionImage fvi = FirebaseVisionImage.fromByteArray(frame.getData(),metadata);
                    final FirebaseVisionFace[] fc = new FirebaseVisionFace[1];
                    detector.detectInImage(fvi).addOnSuccessListener(new OnSuccessListener<List<FirebaseVisionFace>>() {
                        @Override
                        public void onSuccess(List<FirebaseVisionFace> firebaseVisionFaces) {
                           for(FirebaseVisionFace f : firebaseVisionFaces)
                                {
                                    ov.previewh = previewh;
                                    ov.previeww = previeww;
                                    ov.face = f;
                                    ov.invalidate();
                                }

                        }
                    }).addOnFailureListener(new OnFailureListener() {
                        @Override
                        public void onFailure(@NonNull Exception e) {

                        }
                    });
                }
            }
        });
    }

    @Override
    protected void onResume() {
        super.onResume();
        cv.start();
    }

    @Override
    protected void onPause() {
        super.onPause();
        cv.stop();
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        cv.destroy();
    }
}

это оверлейный код

public class OverlayView extends View {

    public int previewh;
    public int previeww;
    public FirebaseVisionFace face;
    public Rect rect;
    private float widthScaleFactor = 1.0f;
    private float heightScaleFactor = 1.0f;
    Context c;
    Bitmap draw = BitmapFactory.decodeResource(getResources(),R.drawable.pimg);


    public OverlayView(Context context, AttributeSet attr) {
        super(context,attr);
        this.c = context;
        this.postInvalidate();

    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        if(face!= null && canvas != null && previewh != 0 && previeww != 0)
        {
            widthScaleFactor = getWidth()/previeww;
            heightScaleFactor = getHeight()/previewh;
            float maxx = 0;
            float minx = 10000;
            float maxy = 0;
            float miny = 10000;
            List<FirebaseVisionPoint> facce3= face.getContour(FirebaseVisionFaceContour.ALL_POINTS).getPoints();
            for(FirebaseVisionPoint f : facce3)
            {
                Paint p1 = new Paint();
                p1.setStyle(Paint.Style.FILL);
                p1.setColor(Color.GREEN);
                p1.setStrokeWidth(5);
                canvas.drawPoint(translateX(f.getX()+50),translateY(f.getY()+50),p1);
            }


            maxx = translateX(maxx);
            minx = translateX(minx);
            maxy = translateY(maxy);
            miny = translateY(miny);
            //Log.d("texts", "onDraw: "+maxx+"  "+minx+" "+maxy+"  "+miny);
            Rect r1 = new Rect(Math.round(maxx),Math.round(miny),Math.round(minx),Math.round(maxy));

        }
    }

    private float translateX(Float x) {
        return getWidth()-scaleX(x);
    }

    private float scaleX(Float x) {
        return x*widthScaleFactor;
    }

    private float translateY(Float x) {
        Resources resources = c.getResources();
        int resourceId = resources.getIdentifier("navigation_bar_height", "dimen", "android");
        return (scaleY(x)+resources.getDimensionPixelSize(resourceId));
    }

    private float scaleY(Float x) { return x*heightScaleFactor; }
}

я попытался настроить значения X и Y, добавив в него некоторые значенияно в итоге оказалось, что одна из сторон не покрыта точками, тогда

, что можно сделать, чтобы выровнять ее по всем сторонам.

1 Ответ

0 голосов
/ 13 февраля 2019

Вы можете проверить GraphicOverlay.java на официальном firebase / quickstart-android репозитории :

 /**
 * Adjusts the x coordinate from the preview's coordinate system to the view coordinate system.
 */
public float translateX(float x) {
  if (overlay.facing == CameraSource.CAMERA_FACING_FRONT) {
    return overlay.getWidth() - scaleX(x);
  } else {
    return scaleX(x);
  }
}

/**
 * Adjusts the y coordinate from the preview's coordinate system to the view coordinate system.
 */
public float translateY(float y) {
  return scaleY(y);
}

ТакжеВы можете ознакомиться с официальной документацией по распознаванию лиц: Обнаружение лиц с помощью MK Kit на Android .

...