建议释放 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 called 在 CameraWorker
来自 JavaCameraView
:
...
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
是一个 is reused 每个新帧的垫子 -> 你不必释放它。
在rgba()
的情况下:
mYuvFrameData
转换为 mRgba
。 mRgba
是在构造函数中初始化并每次重用的 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矩阵是直接赋值的,但是上一个没有发布.
所以我们有两个选择:
- 重复使用我们的 return 矩阵,将其转换为 class 成员(推荐)。
- 修改
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
...
}
我在使用 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 called 在 CameraWorker
来自 JavaCameraView
:
...
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
是一个 is reused 每个新帧的垫子 -> 你不必释放它。
在rgba()
的情况下:
mYuvFrameData
转换为 mRgba
。 mRgba
是在构造函数中初始化并每次重用的 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矩阵是直接赋值的,但是上一个没有发布.
所以我们有两个选择:
- 重复使用我们的 return 矩阵,将其转换为 class 成员(推荐)。
- 修改
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
...
}