ArCore: How to improve image tracking and anchor stability?

Viewed 109

I'm developing an Android app for recognizing augmented images and displaying videos directly over them. I have implemented everything and it's working well but the only issue is that the anchorNode model that gets attached to the augmented image anchor isn't very stable and doesn't remain exactly in the image's frame. I tried to follow some best practices for improving tracking and got better results but there is only one point that I'm not understanding which is "If your image will never move from its initial position (for example, a poster affixed to a wall), you can attach a global anchor to the image to increase tracking stability.", could someone help explain how to that , please? and It would be great if I can get some tips for improving tracking evermore. Thanks in advance. Here is the code I'm using for tracking and creating video anchors.

    override fun onSessionConfiguration(session: Session?, config: Config?) {

    Log.d("ttt","onSessionConfiguration")
    this.session = session
    // Disable plane detection
    config!!.planeFindingMode = Config.PlaneFindingMode.DISABLED

    Thread().run {

        database = AugmentedImageDatabase(session).also {
            for(fileName in requireContext().fileList().filter { it.contains("image.jpg") }){
                    val file = File(requireContext().filesDir,fileName)
                    if(file.exists()){
                        it.addImage(fileName.toString().split("-")[0],BitmapFactory.decodeFile(file.absolutePath),0.25f)
                    }
                }
        }

        config.setAugmentedImageDatabase(database)


    }

    arFragment?.setOnAugmentedImageUpdateListener { it->
        run {
            onAugmentedImageTrackingUpdate(it)
        }
    }



}

    private fun onAugmentedImageTrackingUpdate(augmentedImage: AugmentedImage) {

    attachVideo(augmentedImage)

}
  private fun attachVideo(augmentedImage: AugmentedImage){

        if (augmentedImage.trackingState == TrackingState.TRACKING
            && augmentedImage.trackingMethod == AugmentedImage.TrackingMethod.FULL_TRACKING){

            if (!matrixDetected) {

                matrixDetected = true
                lastTracketedImageName = augmentedImage.name

                anchorNode = AnchorNode(augmentedImage.createAnchor(augmentedImage.centerPose))
                anchorNode!!.isSmoothed = true

                texture = ExternalTexture().also {
                    it.surfaceTexture.setOnFrameAvailableListener {
                        texture!!.surfaceTexture.setOnFrameAvailableListener(null)

                        val model = ShapeFactory.makeCube(
                            Vector3(augmentedImage.extentX,0f,augmentedImage.extentZ),
                            Vector3(0f,0f,0f),
                            plainVideoMaterial
                        )


                        model.isShadowReceiver = false
                        model.isShadowCaster = false

                        val renderable  = anchorNode!!.setRenderable(model)
                        renderable.material!!.setExternalTexture("videoTexture",texture)

                        fadeInVideo(renderable.material)
                    }

                }

                val videoFile = File(requireContext().filesDir,"${augmentedImage.name}-video.mp4")

                mediaPlayer = MediaPlayer.create(requireContext(),Uri.fromFile(videoFile)).also {
                    it.isLooping = true
                    it.setSurface(texture!!.surface)
                    it.start()
                }

                arFragment!!.arSceneView.scene.addChild(anchorNode)

            }


        }else{



            if(matrixDetected){

                if(anchorNode != null){
                    arFragment!!.arSceneView.scene.removeChild(anchorNode!!)
                    anchorNode = null
                }

                viewLifecycleOwner.lifecycleScope.launch {
                    val result = viewModel.endArVideo(deviceID,augmentedImage.name)

                    if(result.isSuccessful){

                        Log.d("ttt","stop ar request success")

                    }else{
                        Log.d("ttt","stop ar request failed ${result.errorBody()}")

                    }
                }

                matrixDetected = false

            }

            mediaPlayer?.let {
                it.setSurface(null)
                it.stop()
                it.release()
                mediaPlayer = null
            }


        }


}


private fun fadeInVideo(material: Material) {


    ValueAnimator.ofFloat(0f, 1f).apply {
        duration = 500L
        interpolator = LinearInterpolator()
        addUpdateListener { v ->
            material.setFloat("videoAlpha", v.animatedValue as Float)
        }

    }.start()
}
0 Answers
Related