增强面部API(ARCore)-如何在Android Studio中使用按钮替换面罩?

4
我正在使用ARCore-Augmented Faces API在Android Studio上开发AR Android应用程序。目前,我已经完成了应用程序的设置(5个按钮和它们关联的3D模型),当我首次点击其中一个按钮启动应用程序时,它运行得很好。问题是当我点击另一个按钮以更换当前面罩时,它不会用新的面罩替换当前面罩。
然而,为了解决这个问题,我尝试使用restart()方法并尝试删除facenode。但是似乎这些解决方案都没有起作用。
这是我目前正在处理的代码部分(不是修复的代码),我仍然困扰着我遇到的问题。

        alchemist_ovalbtn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                alchemistOval();
            }
        });

        scene.addOnUpdateListener(
                (FrameTime frameTime) -> {
                    if (faceRegionsRenderable == null) {
                        return;
                    }

                    Collection<AugmentedFace> faceList =
                            sceneView.getSession().getAllTrackables(AugmentedFace.class);

                    // Make new AugmentedFaceNodes for any new faces.
                    for (AugmentedFace face : faceList) {
                        if (!faceNodeMap.containsKey(face)) {
                            AugmentedFaceNode faceNode = new AugmentedFaceNode(face);
                            faceNode.setParent(scene);
                            faceNode.setFaceRegionsRenderable(faceRegionsRenderable);
                            faceNode.setFaceMeshTexture(faceMeshTexture);
                            faceNodeMap.put(face, faceNode);
                        }
                    }

                });

// Remove any AugmentedFaceNodes associated with an AugmentedFace that stopped tracking.

        Iterator<Map.Entry<AugmentedFace, AugmentedFaceNode>> iter =
                faceNodeMap.entrySet().iterator();
        while (iter.hasNext()) {
            Map.Entry<AugmentedFace, AugmentedFaceNode> entry = iter.next();
            AugmentedFace face = entry.getKey();
            if (face.getTrackingState() == TrackingState.STOPPED) {
                AugmentedFaceNode faceNode = entry.getValue();
                faceNode.setParent(null);
                iter.remove();
            }
        }

public void alchemistOval() {

        ModelRenderable.builder()
                .setSource(this, R.raw.alchemist_oval)
                .build()
                .thenAccept(
                        modelRenderable -> {
                            faceRegionsRenderable = modelRenderable;
                            modelRenderable.setShadowCaster(false);
                            modelRenderable.setShadowReceiver(false);
                        });

    }

因此,当用户单击另一个按钮时,我预计当前的口罩将被新口罩替换。

你得到任何答案了吗? - tej shah
1
你找到解决方案了吗? - Sanjeev
@khairudin,你找到解决方案了吗?我也在寻找同样的解决方案,但是没有找到任何解决方案,请帮帮我,如果你找到了任何解决方案。 - Mallikarjun Hampannavar
1个回答

0
这段代码可以在点击时在三个面罩之间进行切换,希望能对您有所帮助。
package com.example.faceplay;

import androidx.appcompat.app.AppCompatActivity;

import android.os.Build;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.ImageView;

import com.google.ar.core.AugmentedFace;
import com.google.ar.core.TrackingState;
import com.google.ar.sceneform.ArSceneView;
import com.google.ar.sceneform.FrameTime;
import com.google.ar.sceneform.Scene;
import com.google.ar.sceneform.rendering.ModelRenderable;
import com.google.ar.sceneform.rendering.Renderable;
import com.google.ar.sceneform.rendering.Texture;
import com.google.ar.sceneform.ux.AugmentedFaceNode;

import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

public class MainActivity extends AppCompatActivity implements View.OnClickListener {


    private FaceFragment arFragment;

    private Texture faceMeshTexture;
    Scene scene;
    ArSceneView sceneView;
    AugmentedFaceNode faceNode;

    private final HashMap<AugmentedFace, AugmentedFaceNode> faceNodeMap = new HashMap<>();

    ImageView mask, eyemask, skull_1;
    View arrayView[];

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        arFragment = (FaceFragment) getSupportFragmentManager().findFragmentById(R.id.face_fragment);



        mask = (ImageView)findViewById(R.id.mask);
        eyemask = (ImageView)findViewById(R.id.eyemask);
        skull_1 = (ImageView)findViewById(R.id.skull_1);

        setArrayView();
        setClickListener();


        sceneView = arFragment.getArSceneView();
        sceneView.setCameraStreamRenderPriority(Renderable.RENDER_PRIORITY_FIRST);
        scene = sceneView.getScene();



        scene.addOnUpdateListener(

                (FrameTime frameTime) -> {

                    if ( faceMeshTexture == null) {
                        return;
                    }

                    Collection<AugmentedFace> faceList =
                            sceneView.getSession().getAllTrackables(AugmentedFace.class);

                    for (AugmentedFace face : faceList) {

                        if (!faceNodeMap.containsKey(face)) {

                           faceNode = new AugmentedFaceNode(face);

                            faceNode.setParent(scene);
                            faceNode.setFaceMeshTexture(faceMeshTexture);

                            faceNodeMap.put(face, faceNode);

                        }

                    }

                });
    }

    private void AugmentedFaceDisplay(int resource){

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
            Texture.builder()
                    .setSource(this, resource)
                    .build()
                    .thenAccept(texture -> faceMeshTexture = texture);
        }


    }

    private void setArrayView(){
        arrayView = new View[]{
                mask, eyemask, skull_1
        };
    }

    private void setClickListener(){
        for ( int i = 0; i < arrayView.length; i++){
            arrayView[i].setOnClickListener(this);
        }
    }

    @Override
    public void onClick(View v) {

        // First face mask 
        if( v.getId() == R.id.mask )
        {
            faceNodeMap.clear();
            try{
                faceNode.setParent(null);
            }
            catch (Exception e){

            }

            AugmentedFaceDisplay(R.drawable.mask);
        }

        // Second face mask      
        else  if( v.getId() == R.id.eyemask)
        {
            faceNodeMap.clear();
            try{
                faceNode.setParent(null);
            }
            catch (Exception e){

            }
            AugmentedFaceDisplay(R.drawable.eyemask);
        }

        // Third face mask 
        else  if( v.getId() == R.id.skull_1 )
        {
            faceNodeMap.clear();
            try{
                faceNode.setParent(null);
            }
            catch (Exception e){

            }
            AugmentedFaceDisplay(R.drawable.skull1);
        }
    }
}


该代码实现了在单击时在三种口罩之间交换,希望能对您有所帮助。 - Hur Ali

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