带有 OpenCV 人脸检测的 OpenGL 字节缓冲区

Posted

技术标签:

【中文标题】带有 OpenCV 人脸检测的 OpenGL 字节缓冲区【英文标题】:OpenGL byte-buffer with OpenCV face detection 【发布时间】:2016-01-26 21:42:28 【问题描述】:

我正在尝试使用 OpenCV 和 OpenGL 在脸上叠加贴纸。

我正在 onDrawFrame 中获取 ByteBuffer:

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

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

        byteBuffer.rewind();
        GLES20.glReadPixels(0, 0, mWidth, mHeight, GLES20.GL_RGBA, GLES20.GL_UNSIGNED_BYTE, byteBuffer);
        mat.put(0, 0, byteBuffer.array());

        if (mCascadeClassifier != null) 
            mFaces.empty();
            mCascadeClassifier.detectMultiScale(mat, mFaces);
            Log.d(TAG, "No. of faces detected : " + mFaces.toArray().length);
        

        drawFrame(mTextureId, mSTMatrix);

我的垫子对象被初始化为相机预览的宽度和高度:

mat = new Mat(height, width, CvType.CV_8UC3);

日志返回 0 人脸检测。我有两个问题:

    我在使用 OpenCV 进行人脸检测时缺少什么? 另外,如何提高视频帧渲染的性能/效率并进行实时人脸检测?因为 glReadPixels 需要时间来执行并减慢渲染速度。

【问题讨论】:

【参考方案1】:

在渲染任何内容之前,您正在 GLES 帧缓冲区上调用 glReadPixels()。如果您希望读回 SurfaceTexture 渲染,则需要在 drawFrame() 之后执行此操作。您可能需要考虑将屏幕外的纹理渲染到 pbuffer EGLSurface,然后从中读取。

有几种不同的方法可以从相机中获取像素数据:

    使用相机字节[] API。通常涉及软件副本,因此速度较慢。 将输出发送到ImageReader。这使您可以立即访问原始 YUV 数据。 将输出发送到 SurfaceTexture,渲染纹理,使用glReadPixels() 读取 RGB 数据(我相信您正在尝试这样做)。这通常非常快,但在某些设备和 android 版本上可能会很慢。

【讨论】:

再次感谢您强调问题。我是 OpenGL 的新手,因此难以理解 OffScreen 缓冲区。 EglSurfaceBase(grafika project) createOffscreenSurface 中有一个方法,但我不确定,我该如何使用它。为了澄清,我应该有两个渲染表面(正常和离屏),glReadPixels 应该发生在离屏表面,我应该使用 OpenCV 处理帧,然后将编辑的帧渲染到正常表面。如果您向我推荐一些处理类似情况的示例,那就太好了。 我不知道涉及 OpenCV 的示例。 ContinuousCaptureActivity 的drawFrame() 在渲染时在两个表面(一个用于显示,一个用于视频)之间切换。 TextureUploadActivity 基准将其所有渲染到屏幕外表面,然后使用saveFrame()(使用glReadPixels())保存最后一个的副本以进行调试。所以各种片段都在那里,但在 Grafika 中没有完整的示例。 这太棒了!衷心感谢您一直以来的帮助。 :) ImageReaderCamera2。永远不要使用 Camera2 API! (许多制造商没有正确实施)github.com/googlesamples/android-Camera2Basic/issues/123

以上是关于带有 OpenCV 人脸检测的 OpenGL 字节缓冲区的主要内容,如果未能解决你的问题,请参考以下文章

如何以及在何处使用带有 QT 的 basler 相机实现 opencv 人脸检测代码

OpenCV&Qt学习之四——OpenCV 实现人脸检测与相关知识整理

当帧中没有人脸时,OpenCV 中的人脸检测器会变慢

带有 OpenCV 和 OpenGL 的 AR

opencv 是怎么实现人脸检测的

opencv 人脸检测中的xml可以修改吗