2015-10-20 57 views
1

我试图在相机预览帧上应用人脸检测。我正在使用OpenGL和OpenCV在运行时处理这些相机帧。使用OpenGL的Android相机帧处理

@Override 
    public void onDrawFrame(GL10 unused) { 
     if (VERBOSE) { 
      Log.d(TAG, "onDrawFrame tex=" + mTextureId); 
     } 

     mSurfaceTexture.updateTexImage(); 
     mSurfaceTexture.getTransformMatrix(mSTMatrix); 

     // TODO: need to implement 
     //JniCppManager.processFrame(); 

     drawFrame(mTextureId, mSTMatrix); 
} 

我想实现processFrame()的C++实现。我如何从转换矩阵中获取C++中的Mat对象?任何人都可以向我提供一些解决方案的指针。

+0

来自'getTransformMatrix()'的值是一个4x4矩阵,表示为按列主序排列的16元素线性数组。 OpenCV'Mat'类当然可以表示这一点,但是您是否试图获取(通常是平凡的)转换矩阵或像素数据本身并不清楚。 – fadden

+0

感谢Fadden的回应。我最终的目标是覆盖基于图像识别的静态图像。例如在特定的地标上覆盖胡须。我认为我需要像素数据。 – muneikh

回答

3

你的管道是目前:

  • 相机(产生帧)
  • 表面纹理(接收帧,转换为GLES “外部” 纹理)
  • [缺少的东西]
  • 阵列的RGB字节传递给C++

你需要为[缺少的东西]做什么是将像素渲染到屏幕外的pbuffer和rea回到glReadPixels()。您可以使用Java或原生代码编写代码;对于前者,您希望将它们读入“直接”ByteBuffer中,以便您可以轻松地从本机代码访问像素。 GLES使用的EGL上下文保存在线程本地存储中,因此在GLSurfaceView渲染线程上运行的本机代码将能够访问它。

一个例子可以在大片ExtractMpegFramesTest中找到,主要区别在于它从视频而不是相机抓取帧。

对于API 19+,如果您可以使用YV12或NV21而不是RGB处理帧,则可以将相机送入ImageReader,并且无需复制/转换即可访问数据。

+0

谢谢法登,你的回答非常有帮助! – muneikh