建议发布CvCameraViewFrame inputFrame?

Fra*_*ado 2 android opencv opencv4android opencv3.1

我正在使用的Android应用程序中工作JavaCameraView.所以在我的活动中我实施CvCameraViewListener2.

我的实现onCameraFrame()看起来像这样:

@Override
public Mat onCameraFrame(CvCameraViewFrame inputFrame) {
    final Mat frame = inputFrame.rgba();
    return bs.process(frame);
}
Run Code Online (Sandbox Code Playgroud)

我的问题是:如果我发布,frame因为我不再使用它会不会很好?所以做这样的事情:

@Override
public Mat onCameraFrame(CvCameraViewFrame inputFrame) {
    final Mat frame = inputFrame.rgba();
    Mat result = bs.process(frame);
    frame.release();
    return result;
}
Run Code Online (Sandbox Code Playgroud)

谢谢你的帮助.

Dav*_*uel 5

不必释放inputFrame矩阵,但必须小心返回矩阵.

说明:

onCameraFrame()回调被调用deliverAndDrawFrame()方法来自CameraBridgeViewBase:

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

deliverAndDrawFrame()方法在from中调用:CameraWorkerJavaCameraView

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

mCameraFrame是一个JavaCameraFrame类型的数组.如果你看这个类,你可以看到矩阵的来源:

@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;
}
Run Code Online (Sandbox Code Playgroud)

在以下情况下gray():

mYuvFrameData是一个可以在每个新框架中重复使用的垫子- >您不必释放它.

在以下情况下rgba():

mYuvFrameData转换为mRgba.mRgba是在构造函数中初始化并每次重用的类成员.该cvtColor()方法使用create()方法在dst矩阵中分配空间.此方法如下(JavaDoc):

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

所以,在这种情况下你也没有释放.

返回矩阵

如果我们再看一下deliverAndDrawFrame()方法的代码,我们可以看到我们的返回矩阵是如何处理的:

...
modified = mListener.onCameraFrame(frame);
...
Run Code Online (Sandbox Code Playgroud)

我们的返回矩阵是直接分配的,但前一个没有发布.

所以我们有两个选择:

  1. 重用我们的返回矩阵将其转换为类成员(推荐).
  2. 修改CameraBridgeViewBase 源代码,添加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;
}
Run Code Online (Sandbox Code Playgroud)

选项2:

protected void deliverAndDrawFrame(CvCameraViewFrame frame) {
    ...
    boolean bmpValid = true;
    if (modified != null) {
        try {
            Utils.matToBitmap(modified, mCacheBitmap);
            modified.release(); // Add this line
            ...
}
Run Code Online (Sandbox Code Playgroud)