Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/gwt/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Google project tango 在Jacobi Google Tango API中使用onFrameAvailable()_Google Project Tango - Fatal编程技术网

Google project tango 在Jacobi Google Tango API中使用onFrameAvailable()

Google project tango 在Jacobi Google Tango API中使用onFrameAvailable(),google-project-tango,Google Project Tango,问题:有人知道如何使用Tango Java(Jacobi)APIonFrameAvailable()回调获取Tango的彩色相机图像缓冲区吗 背景: 我有一个增强现实应用程序,在探戈的背景下显示视频。我已经使用以下JavaAPI(Jacobi)成功创建了视频覆盖示例。我的应用程序工作正常,视频在背景中正确渲染 作为应用程序的一部分,我希望在用户按下按钮时存储视频backbuffer的副本。因此,我需要访问相机的RGB数据 根据,任何希望访问摄像头RGB数据的类都应该在OnTangoUpdateL

问题:有人知道如何使用Tango Java(Jacobi)API
onFrameAvailable()
回调获取Tango的彩色相机图像缓冲区吗

背景:

我有一个增强现实应用程序,在探戈的背景下显示视频。我已经使用以下JavaAPI(Jacobi)成功创建了视频覆盖示例。我的应用程序工作正常,视频在背景中正确渲染

作为应用程序的一部分,我希望在用户按下按钮时存储视频backbuffer的副本。因此,我需要访问相机的RGB数据

根据,任何希望访问摄像头RGB数据的类都应该在
OnTangoUpdateListener
中实现新的
onFrameAvailable()
方法。我这样做了,但我没有看到任何句柄或参数来实际获取像素:

Java API

@Override
public void onFrameAvailable(int cameraId) {
    //Log.w(TAG, "Frame available!");
    if (cameraId == TangoCameraIntrinsics.TANGO_CAMERA_COLOR) {
        tangoCameraPreview.onFrameAvailable();
    }
}
TangoErrorType TangoService_connectOnFrameAvailable(
    TangoCameraId id, void* context,
    void (*onFrameAvailable)(void* context, TangoCameraId id,
                             const TangoImageBuffer* buffer));
如图所示,
onFrameAvailable
只有一个参数和整数,用于指定生成视图的相机的id。与C-library回调相比,C-library回调提供对图像缓冲区的访问:

C API

@Override
public void onFrameAvailable(int cameraId) {
    //Log.w(TAG, "Frame available!");
    if (cameraId == TangoCameraIntrinsics.TANGO_CAMERA_COLOR) {
        tangoCameraPreview.onFrameAvailable();
    }
}
TangoErrorType TangoService_connectOnFrameAvailable(
    TangoCameraId id, void* context,
    void (*onFrameAvailable)(void* context, TangoCameraId id,
                             const TangoImageBuffer* buffer));
我希望Java方法与C API调用中的buffer对象类似

我尝试过的

我尝试扩展
TangoCameraPreview
类并将图像保存在那里,但只得到了黑色背景

public class CameraSurfaceView extends TangoCameraPreview {


    private boolean takeSnapShot = false;

    public void takeSnapShot() {
        takeSnapShot = true;
    }

    /**
     * Grabs a copy of the surface (which is rendering the Tango color camera)
     * https://stackoverflow.com/questions/14620055/how-to-take-a-screenshot-of-androids-surface-view
     */
    public void screenGrab2(){

        int width = this.getWidth();
        int height = this.getHeight();
        long fileprefix = System.currentTimeMillis();

        View v= getRootView();
         v.setDrawingCacheEnabled(true);
        // this is the important code :)  
        // Without it the view will have a dimension of 0,0 and the bitmap will be null          
        v.measure(MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED),
        MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED));
        v.layout(0, 0, width, height);

        v.buildDrawingCache(true);

        Bitmap image = v.getDrawingCache();

        //TODO:  make seperate subdirctories for each exploitation sessions
        String targetPath =Environment.getExternalStorageDirectory()  + "/RavenEye/Photos/";
        String imageFileName = fileprefix + ".jpg";   

        if(!(new File(targetPath)).exists()) {
            new File(targetPath).mkdirs();
        }

        try {           
            File targetDirectory = new File(targetPath);
            File photo=new File(targetDirectory, imageFileName);
            FileOutputStream fos=new FileOutputStream(photo.getPath());
            image.compress(CompressFormat.JPEG, 100, fos);          
            fos.flush();
            fos.close();
            Log.i(this.getClass().getCanonicalName(), "Grabbed an image in target path:" + targetPath);
        } catch (FileNotFoundException e) {
            Log.e(CameraPreview.class.getName(),"Exception " + e);
            e.printStackTrace();
        } catch (IOException e) {
            Log.e(CameraPreview.class.getName(),"Exception " + e);
            e.printStackTrace();
        }   

    }


    /**
     * Grabs a copy of the surface (which is rendering the Tango color camera)
     */
    public void screenGrab(){

        int width = this.getWidth();
        int height = this.getHeight();
        long fileprefix = System.currentTimeMillis();

        Bitmap image = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);

        Canvas canvas = new Canvas(image);
        canvas.drawBitmap(image, 0, 0, null);

        //TODO:  make seperate subdirctories for each exploitation sessions
        String targetPath =Environment.getExternalStorageDirectory()  + "/RavenEye/Photos/";
        String imageFileName = fileprefix + ".jpg";   

        if(!(new File(targetPath)).exists()) {
            new File(targetPath).mkdirs();
        }

        try {           
            File targetDirectory = new File(targetPath);
            File photo=new File(targetDirectory, imageFileName);
            FileOutputStream fos=new FileOutputStream(photo.getPath());
            image.compress(CompressFormat.JPEG, 100, fos);          
            fos.flush();
            fos.close();
            Log.i(this.getClass().getCanonicalName(), "Grabbed an image in target path:" + targetPath);
        } catch (FileNotFoundException e) {
            Log.e(CameraPreview.class.getName(),"Exception " + e);
            e.printStackTrace();
        } catch (IOException e) {
            Log.e(CameraPreview.class.getName(),"Exception " + e);
            e.printStackTrace();
        }   

    }

    @Override
    public void onFrameAvailable() {
        super.onFrameAvailable();
        if(takeSnapShot) {
            screenGrab();
            takeSnapShot = false;

        }
    }

    public CameraSurfaceView(Context context) {
        super(context);
        // TODO Auto-generated constructor stub
    }
}
我要去哪里

我正准备为设备设置根目录,然后使用
onFrameAvailable
方法提示外部根目录进程,如以下其中一个:

我希望我能找到一种避免根黑客攻击的方法


提前感谢您

我还没有在最新版本上试用过,但正是由于缺乏这一功能,我才转向C API,在那里我可以获取图像数据——我认为最近在G+页面上的一篇帖子似乎表明Unity API现在也返回图像数据——对于一家希望在我们不使用Java时不断责骂我们的公司来说,这当然是一个奇怪的滞后:-)

好的,我想出了一个办法让它工作

更新:我的工作解决方案如下:

我在渲染管道上设置了一个“中间人(渲染器)”攻击。 这种方法截取来自
TangoCameraPreview
基类的
SetRenderer
调用,并允许访问 到基本渲染器的
OnDraw()
方法和GL上下文。然后,我向这个扩展的渲染器添加额外的方法,允许读取GL缓冲区

一般方法

1) 扩展
TangoCameraPreview
类(例如,在我的示例中
ReadableTangoCameraPreview
)。覆盖
setRenderer(GLSurfaceView.Renderer Renderer)
,保留对基本渲染器的引用,并使用您自己的“包装”GLSUrface.Renderer替换渲染器,该渲染器将添加将backbuffer渲染到设备上图像的方法

2) 创建自己的
GLSurfaceView.Renderer
接口(例如my
ScreenGrabRenderer
类),该接口实现所有
GLSurfaceView.Renderer
方法,并将它们传递到步骤1中捕获的基本渲染器。另外,当你想要抓取图像时,给“提示”添加一些新方法

3) 执行上面步骤2中描述的
屏幕抓取渲染器

4) 复制图像时,使用回调接口(my
TangoCamerasScreenGrabCallback
)进行通信

它工作得很好,可以在图像中抓取相机位,而无需在设备上生根

注意:我没有必要将捕获的图像与点云紧密同步。所以我没有检查延迟。为了获得最佳结果,您可能需要调用Mark提出的C方法

下面是我的每个班级的样子

///Main Activity Class where bulk of Tango code is
.
.
.

// Create our Preview view and set it as the content of our activity.
mTangoCameraPreview = new ReadableTangoCameraPreview(getActivity());

RelativeLayout preview = (RelativeLayout) view.findViewById(R.id.camera_preview);
preview.addView(mTangoCameraPreview);


.
.
.
//When you want to take a snapshot, call the takeSnapShotMethod()
//(you can make this respond to a button)
mTangoCameraPreview.takeSnapShot();
.
.
.
.
.
//Main Tango Listeners
@Override
public void onFrameAvailable(final int cameraId) {
    // Update the UI with TangoPose information
    runOnUiThread(new Runnable() {
        @Override
        public void run() {
            if (cameraId == TangoCameraIntrinsics.TANGO_CAMERA_COLOR) {
                tangoCameraPreview.onFrameAvailable();
            }       
        }
    });
}

ReadableTangoCameraPreview类

public class ReadableTangoCameraPreview extends TangoCameraPreview implements  TangoCameraScreengrabCallback  {

    Activity mainActivity;
    private static final String TAG = ReadableTangoCameraPreview.class.getSimpleName();

    //An intercept renderer
    ScreenGrabRenderer screenGrabRenderer;

    private boolean takeSnapShot = false;

    @Override
    public void setRenderer(GLSurfaceView.Renderer renderer) {  
        //Create our "man in the middle"
        screenGrabRenderer= new ScreenGrabRenderer(renderer);

        //Set it's call back
        screenGrabRenderer.setTangoCameraScreengrabCallback(this);

        //Tell the TangoCameraPreview class to use this intermediate renderer
        super.setRenderer(screenGrabRenderer);
        Log.i(TAG,"Intercepted the renderer!!!");       
    }


    /**
     * Set a trigger for snapshot.  Call this from main activity
     * in response to a use input
     */
    public void takeSnapShot() {
        takeSnapShot = true;
    }   

    @Override
    public void onFrameAvailable() {
        super.onFrameAvailable();
        if(takeSnapShot) {
            //screenGrabWithRoot();
            screenGrabRenderer.grabNextScreen(0,0,this.getWidth(),this.getHeight());
            takeSnapShot = false;           
        }
    }

    public ReadableTangoCameraPreview(Activity context) {
        super(context); 
        mainActivity = context;     

    }

    public void newPhoto(String aNewPhotoPath) {
        //This gets called when a new photo was  grabbed created in the renderer
        Log.i(TAG,"New image available at" + aNewPhotoPath);    
    }

}

屏幕抓取渲染器界面

(重载TangoCameraPreview默认渲染器)


太棒了-Java人会喜欢这个的,你给了他们谷歌没有的东西!是的,现在速度很慢,有时我复制片段时会挂起探戈线。我将继续玩它,看看我是否能发布一些演示代码。。。