带有 OpenCV 人脸检测的 OpenGL 字节缓冲区
OpenGL byte-buffer with OpenCV face detection
我正在尝试使用 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 对象在相机预览宽度和高度中初始化:
mat = new Mat(height, width, CvType.CV_8UC3);
日志return 0 人脸检测。我有两个问题:
- 使用 OpenCV 进行人脸检测我错过了什么?
- 还有,如何提高视频帧渲染performance/efficiency和实时人脸检测?因为 glReadPixels 需要时间来执行并减慢渲染速度。
您在渲染任何内容之前在 GLES 帧缓冲区上调用 glReadPixels()
。如果您希望读回 SurfaceTexture 渲染,则需要在 drawFrame()
之后执行此操作。您可能需要考虑将屏幕外的纹理渲染到 pbuffer EGLSurface,然后从中读取。
有几种不同的方法可以从相机中获取像素数据:
- 使用相机字节[] API。一般涉及软件拷贝,所以往往比较慢。
- 将输出发送到 ImageReader。这使您可以立即访问原始 YUV 数据。
- 将输出发送到 SurfaceTexture,渲染纹理,使用
glReadPixels()
读取 RGB 数据(我相信您正在尝试这样做)。这通常非常快,但在 Android 的某些设备和版本上可能会很慢。
我正在尝试使用 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 对象在相机预览宽度和高度中初始化:
mat = new Mat(height, width, CvType.CV_8UC3);
日志return 0 人脸检测。我有两个问题:
- 使用 OpenCV 进行人脸检测我错过了什么?
- 还有,如何提高视频帧渲染performance/efficiency和实时人脸检测?因为 glReadPixels 需要时间来执行并减慢渲染速度。
您在渲染任何内容之前在 GLES 帧缓冲区上调用 glReadPixels()
。如果您希望读回 SurfaceTexture 渲染,则需要在 drawFrame()
之后执行此操作。您可能需要考虑将屏幕外的纹理渲染到 pbuffer EGLSurface,然后从中读取。
有几种不同的方法可以从相机中获取像素数据:
- 使用相机字节[] API。一般涉及软件拷贝,所以往往比较慢。
- 将输出发送到 ImageReader。这使您可以立即访问原始 YUV 数据。
- 将输出发送到 SurfaceTexture,渲染纹理,使用
glReadPixels()
读取 RGB 数据(我相信您正在尝试这样做)。这通常非常快,但在 Android 的某些设备和版本上可能会很慢。