gpt4 book ai didi

android - setPreviewDisplay 和 setDisplayOrientation

转载 作者:塔克拉玛干 更新时间:2023-11-02 08:33:22 31 4
gpt4 key购买 nike

我对 OpenCV 的 Android 相机示例代码感到困惑。他们制作了一个实现 SurfaceHolder.Callback 的自定义类,并将以下行放在方法 surfaceChanged 中:

mCamera.setPreviewDisplay(null);

setPreviewDisplay 的 Android 文档说明:

This method must be called before startPreview(). The one exception is that if the preview surface is not set (or set to null) before startPreview() is called, then this method may be called once with a non-null parameter to set the preview surface. (This allows camera setup and surface creation to happen in parallel, saving time.) The preview surface may not otherwise change while preview is running.

不寻常的是,OpenCV 的代码从不使用非空 SurfaceHolder 调用 setPreviewDisplay。它工作正常,但使用 setDisplayOrientation 更改图像的旋转不起作用。这条线似乎也没有做任何事情,因为没有它我得到了相同的结果。

如果我使用提供给 surfaceChanged 而不是 null 的 SurfaceHolder 调用 setPreviewDisplay,图像会旋转但不包括图像的结果加工。稍后调用 lockCanvas 时,我也会得到一个 IllegalArgumentException

这是怎么回事?

这里是他们代码中(可能)最相关的部分,略微简化并内联方法。这是 the full version .

类定义

public abstract class SampleViewBase extends SurfaceView 
implements SurfaceHolder.Callback, Runnable {

当相机打开时

mCamera.setPreviewCallbackWithBuffer(new PreviewCallback() {
public void onPreviewFrame(byte[] data, Camera camera) {
synchronized (SampleViewBase.this) {
System.arraycopy(data, 0, mFrame, 0, data.length);
SampleViewBase.this.notify();
}
camera.addCallbackBuffer(mBuffer);
}
});

当表面发生变化时

/* Now allocate the buffer */
mBuffer = new byte[size];
/* The buffer where the current frame will be copied */
mFrame = new byte [size];
mCamera.addCallbackBuffer(mBuffer);

try {
mCamera.setPreviewDisplay(null);
} catch (IOException e) {
Log.e(TAG, "mCamera.setPreviewDisplay/setPreviewTexture fails: " + e);
}

[...]

/* Now we can start a preview */
mCamera.startPreview();

运行方法

public void run() {
mThreadRun = true;
Log.i(TAG, "Starting processing thread");
while (mThreadRun) {
Bitmap bmp = null;

synchronized (this) {
try {
this.wait();
bmp = processFrame(mFrame);
} catch (InterruptedException e) {
e.printStackTrace();
}
}

if (bmp != null) {
Canvas canvas = mHolder.lockCanvas();
if (canvas != null) {
canvas.drawBitmap(bmp, (canvas.getWidth() - getFrameWidth()) / 2,
(canvas.getHeight() - getFrameHeight()) / 2, null);
mHolder.unlockCanvasAndPost(canvas);
}
}
}
Log.i(TAG, "Finishing processing thread");
}

最佳答案

我遇到了同样的问题。我没有使用 SurfaceView.Callback,而是将它们的类 JavaCameraView 子类化。看我的活人脸检测和绘制示例here .在处理之前根据设备的方向旋转从相机出来的矩阵是微不足道的。链接代码的相关摘录:

@Override
public Mat onCameraFrame(Mat inputFrame) {
int flipFlags = 1;
if(display.getRotation() == Surface.ROTATION_270) {
flipFlags = -1;
Log.i(VIEW_LOG_TAG, "Orientation is" + getRotation());
}
Core.flip(inputFrame, mRgba, flipFlags);
inputFrame.release();
Imgproc.cvtColor(mRgba, mGray, Imgproc.COLOR_RGBA2GRAY);
if (mAbsoluteFaceSize == 0) {
int height = mGray.rows();
if (Math.round(height * mRelativeFaceSize) > 0) {
mAbsoluteFaceSize = Math.round(height * mRelativeFaceSize);
}
}
}

关于android - setPreviewDisplay 和 setDisplayOrientation,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15562481/

31 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com