我有一个两阶段的应用程序,我需要两组分辨率:
第1阶段
在框架内搜索已知模板 QR标记。为了做到这一点,我需要一个至少640X480的帧大小。
第二阶段找到模板 QR标记后,我需要更改为较低的分辨率(320X240),以便为时间敏感的任务获得最佳帧速率。
我的问题启动时(onCameraViewStarted)我可以将分辨率设置为640X480,但之后我不能从onCameraFrame内更改它(我从onCameraFrame内找到模板 QR标记)。从一些调试,我做的似乎是disconnectCamera()实现的setResolution方法(如在OpenCV教程3中所见)卡住等待主线程完成。在使用新线程或实现事件侦听器时尝试更改分辨率也不正常。
关于如何在两个阶段之间改变分辨率有什么想法吗?
感谢代码:@Override
public Mat onCameraFrame(CameraBridgeViewBase.CvCameraViewFrame inputFrame) {
inFrame = inputFrame.gray();
if (locateTemplate(inFrame)) {
setResolution(WORK_RESOLUTION);
resetGridData(WORK_RESOLUTION);
}
return inFrame;
}
/**
* Sets a new resolution for camera frames
* @param size - the new resolution size
*/
private void setResolution (Size size) {
ListIterator<Camera.Size> iterator = cameraView.getResolutionList().listIterator();
Camera.Size s;
while (iterator.hasNext()) {
s = iterator.next();
if (s.width == size.width && s.height == size.height) {
Log.i(TAG, "Setting resolution to: " + s.width + "X" + s.height);
cameraView.setResolution(s);
}
}
}
我注意到onOptionsItemSelected()从主线程运行setResultion()。
所以…为了让你能够在onCameraFrame()中设置结果,你需要从运行onCameraFrame()的线程异步设置它。
我使用了bolts-android.jar来设置一个在主线程上运行的新任务:
/**
* Sets a new resolution for camera frames
* @param size - the new resolution size
*/
private void setResolution (Size size) {
ListIterator<Camera.Size> iterator = cameraView.getResolutionList().listIterator();
Camera.Size s;
while (iterator.hasNext()) {
s = iterator.next();
if (s.width == size.width && s.height == size.height) {
final Camera.Size resSize = s;
Log.i(TAG, "Setting resolution to: " + resSize.width + "X" + resSize.height);
Task.call(new Callable<Void>() {
@Override
public Void call() throws Exception {
cameraView.setResolution(resSize);
return null;
}
}, Task.UI_THREAD_EXECUTOR);
}
}
}