Я видел много примеров и пытался создать приложение для контурирования лица, и все работало как ожидалось, но по какой-то причине точки не выравнивались с фактическим лицом.
вот мой код активности
<?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, добавив в него некоторые значенияно в итоге оказалось, что одна из сторон не покрыта точками, тогда
, что можно сделать, чтобы выровнять ее по всем сторонам.