建议释放 CvCameraViewFrame inputFrame?

Is recommended to release CvCameraViewFrame inputFrame?

我在使用 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矩阵但是你必须小心你的return 矩阵.

解释:

onCameraFrame() deliverAndDrawFrame() 方法中的回调 is called 来自 CameraBridgeViewBase:

protected void deliverAndDrawFrame(CvCameraViewFrame frame) {
    Mat modified;
    if (mListener != null) {
        modified = mListener.onCameraFrame(frame);
    } else {
        modified = frame.rgba();
    }
    ...
}

deliverAndDrawFrame() 方法 is calledCameraWorker 来自 JavaCameraView:

...
if (!mStopThread && hasFrame) {
    if (!mFrameChain[1 - mChainIdx].empty())
        deliverAndDrawFrame(mCameraFrame[1 - mChainIdx]);
}
...

mCameraFrameJavaCameraFrame类型的数组。如果你看一下 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 是一个 is reused 每个新帧的垫子 -> 你不必释放它。

rgba()的情况下:

mYuvFrameData 转换为 mRgbamRgba 是在构造函数中初始化并每次重用的 class 成员。 cvtColor()方法用create()方法对allocate space in the dst matrix. This method works as follow (JavaDoc):

  • 如果当前数组形状和类型匹配新的,return立即
  • 否则,通过调用 "Mat.release" 取消引用以前的数据。
  • ...

所以,在这种情况下你也没有发布。

Return矩阵

如果我们再次查看 deliverAndDrawFrame() 方法的代码,我们可以看到我们的 return 矩阵是如何处理的:

...
modified = mListener.onCameraFrame(frame);
...

我们的return矩阵是直接赋值的,但是上一个没有发布.

所以我们有两个选择:

  1. 重复使用我们的 return 矩阵,将其转换为 class 成员(推荐)。
  2. 修改CameraBridgeViewBasesource 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
            ...
}