view - 如何在firebase mlkit中正确对齐面部轮廓?
问题描述
我看到了很多例子,并尝试创建一个面部轮廓应用程序,一切都按预期工作,但无论出于何种原因,这些点都没有与实际面部对齐。
这是我的活动代码
<?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 值,但结果发现其中一侧没有被点覆盖
可以做些什么来使它在所有方面都正确对齐。
解决方案
您可以在官方firebase /quickstart-android的存储库中查看 GraphicOverlay.java :
/**
* 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);
}
另外,您可以查看有关人脸识别的官方文档:Detect Faces with MK Kit on Android。
推荐阅读
- python - pip install 之间的区别。和 pip install -e
- python - 如何根据熊猫中的特定列值向列添加值
- ffmpeg - 我可以使用 FFMPEG 在另一台设备上创建一个模拟较低位深度输出的文件吗?
- c# - 如何以更精确和结构化的方式编写以下 C# 代码?
- python - 在odoo 12中上传CSV文件
- docker-compose - 如何在 docker-compose 中使用键盘输入参数?
- android - Android - 导出均衡的音频文件
- c# - 如何使用 MS graph API C# 搜索匹配搜索字符串的所有文档
- java - 为没有注释的类型注册自定义验证器
- javascript - 为数组中的每两个元素创建对