我正在使用 JavaCameraView
的 Android 应用程序。因此,在我的 Activity 中,我实现了CvCameraViewListener2
。
我的 onCameraFrame()
实现如下所示:
@Override
public Mat onCameraFrame(CvCameraViewFrame inputFrame) {
final Mat frame = inputFrame.rgba();
return bs.process(frame);
}
我的问题是:如果我释放 frame
会好吗?因为我不再使用它了?所以要做这样的事情:
@Override
public Mat onCameraFrame(CvCameraViewFrame inputFrame) {
final Mat frame = inputFrame.rgba();
Mat result = bs.process(frame);
frame.release();
return result;
}
感谢您的帮助。
最佳答案
您不必释放inputFrame
矩阵,但您必须小心返回矩阵。
说明:
onCameraFrame()
回调is called在来自 CameraBridgeViewBase
的 deliverAndDrawFrame()
方法中:
protected void deliverAndDrawFrame(CvCameraViewFrame frame) {
Mat modified;
if (mListener != null) {
modified = mListener.onCameraFrame(frame);
} else {
modified = frame.rgba();
}
...
}
deliverAndDrawFrame()
方法 is called在来自 JavaCameraView
的 CameraWorker
中:
...
if (!mStopThread && hasFrame) {
if (!mFrameChain[1 - mChainIdx].empty())
deliverAndDrawFrame(mCameraFrame[1 - mChainIdx]);
}
...
mCameraFrame
是一个JavaCameraFrame
类型的数组。如果你看this class你可以看到矩阵来自哪里:
@Override
public Mat gray() {
return mYuvFrameData.submat(0, mHeight, 0, mWidth);
}
@Override
public Mat rgba() {
Imgproc.cvtColor(mYuvFrameData, mRgba, Imgproc.COLOR_YUV2RGBA_NV21, 4);
return mRgba;
}
如果是gray()
:
mYuvFrameData
是一个 Mat,is reused对于每个新框架 -> 您不必释放它。
如果是rgba()
:
mYuvFrameData
转换为 mRgba
。 mRgba
是在构造函数中初始化并每次重用的类成员。
cvtColor()
方法使用 create()
方法 allocate space在 dst 矩阵中。此方法的工作原理如下( JavaDoc ):
- 如果当前数组形状和类型与新的匹配,立即返回。
- 否则,通过调用“Mat.release”取消引用先前的数据。
- ...
所以,在这种情况下你也不需要释放。
返回矩阵
如果我们再看一下deliverAndDrawFrame()
方法的代码,我们可以看到我们的返回矩阵是如何处理的:
...
modified = mListener.onCameraFrame(frame);
...
我们的返回矩阵是直接赋值的,但是前一个没有发布。
所以我们有两个选择:
- 重用我们的返回矩阵,将其转换为类成员(推荐)。
- 修改
CameraBridgeViewBase
source code ,添加modified.release()
:
选项 1(按照您的示例):
...
private Mat processedFrame;
@Override
public void onCameraViewStarted(int width, int height) {
processedFrame = new Mat();
...
}
@Override
public Mat onCameraFrame(CvCameraViewFrame inputFrame) {
final Mat frame = inputFrame.rgba();
Mat result = bs.process(frame);
result.copyTo(processedFrame);
result.release();
return processedFrame;
}
选项 2:
protected void deliverAndDrawFrame(CvCameraViewFrame frame) {
...
boolean bmpValid = true;
if (modified != null) {
try {
Utils.matToBitmap(modified, mCacheBitmap);
modified.release(); // Add this line
...
}
关于opencv - 是否建议释放CvCameraViewFrame inputFrame?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40203327/