【问题标题】:CameraSource(vision api) not detecting when phone is in landscape modeCameraSource(vision api)未检测到手机何时处于横向模式
【发布时间】:2018-01-26 22:32:22
【问题描述】:

我创建了一个应用程序来使用 Vision api 跟踪眼睛,当手机处于纵向模式时它可以正常工作,但是当我将手机倾斜到横向位置时,应用程序会暂停相机并转到 onMissing() 方法。

请给我一些建议,以便该应用可以在两种布局中运行,或者它可以从任何手机旋转中感知眼睛 (0,90,180,270)

代码:

private void createCameraResources() {
    Context context = getApplicationContext();

    // create and setup the face detector
    mFaceDetector = new FaceDetector.Builder(context)
            .setProminentFaceOnly(true)
            .setTrackingEnabled(true) 
            .setClassificationType(FaceDetector.ALL_CLASSIFICATIONS)
            .setMode(FaceDetector.FAST_MODE) 
            .build();

    mFaceDetector.setProcessor(new LargestFaceFocusingProcessor(mFaceDetector, new FaceTracker()));

    if (!mFaceDetector.isOperational()) {
        Log.w(TAG, "createCameraResources: detector NOT operational");
    } else {
        Log.d(TAG, "createCameraResources: detector operational");
    }
    mCameraSource = new CameraSource.Builder(this, mFaceDetector)
            .setRequestedPreviewSize(640, 480)
            .setFacing(CameraSource.CAMERA_FACING_FRONT)
            .setRequestedFps(30f)
            .build();
}



public class FaceTracker extends Tracker<Face> {

private static final float PROB_THRESHOLD = 0.7f;
private static final String TAG = FaceTracker.class.getSimpleName();
private boolean leftClosed;
private boolean rightClosed;

@Override
public void onUpdate(Detector.Detections<Face> detections, Face face) {
    if (leftClosed && face.getIsLeftEyeOpenProbability() > PROB_THRESHOLD) {
        leftClosed = false;
    } else if (!leftClosed &&  face.getIsLeftEyeOpenProbability() < PROB_THRESHOLD){
        leftClosed = true;
    }
    if (rightClosed && face.getIsRightEyeOpenProbability() > PROB_THRESHOLD) {
        rightClosed = false;
    } else if (!rightClosed && face.getIsRightEyeOpenProbability() < PROB_THRESHOLD) {
        rightClosed = true;
    }

    if (leftClosed && !rightClosed) {
        EventBus.getDefault().post(new LeftEyeClosedEvent());
    } else if (rightClosed && !leftClosed) {
        EventBus.getDefault().post(new RightEyeClosedEvent());
    } else if (!leftClosed && !rightClosed) {
        EventBus.getDefault().post(new NeutralFaceEvent());
    }
}

清单文件:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.android.eyetoggle">

<uses-permission android:name="android.permission.CAMERA" />
<application
    android:allowBackup="true"
    android:icon="@mipmap/ic_launcher"
    android:label="@string/app_name"
    android:supportsRtl="true"
    android:theme="@style/AppTheme">
    <activity
        android:name=".MainActivity">
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />

            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
    </activity>
</application>

</manifest>

对应的XML布局:

<?xml version="1.0" encoding="utf-8"?>
<android.support.percent.PercentFrameLayout       xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="20dp"
tools:context="com.android.eyetoggle.MainActivity">

<LinearLayout
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_gravity="center_horizontal"
    android:orientation="horizontal">

    <android.support.v7.widget.SwitchCompat
        android:id="@+id/switchButton"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />

    <TextView
        android:id="@+id/emoticon"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/emoji_neutral" />
</LinearLayout>


<View
    android:id="@+id/light"
    android:layout_gravity="center"
    android:background="@color/green"
    app:layout_aspectRatio="100%"
    app:layout_widthPercent="75%" />

</android.support.percent.PercentFrameLayout>

【问题讨论】:

  • 介意谷歌搜索android orientation
  • 我已经用谷歌搜索过这个问题,但找不到任何东西。对于hardware.Camera api,有一种方法可以设置显示方向。
  • 这是 Android 基础知识...

标签: android android-orientation vision


【解决方案1】:

您需要检查方向变化并执行类似的操作,

private void startIfReady() throws IOException {
    if (mStartRequested && mSurfaceAvailable) {
        mCameraSource.start(mSurfaceView.getHolder());
        if (mOverlay != null) {
            Size size = mCameraSource.getPreviewSize();
            int min = Math.min(size.getWidth(), size.getHeight());
            int max = Math.max(size.getWidth(), size.getHeight());
            if (isPortraitMode()) {
                // Swap width and height sizes when in portrait, since it will be rotated by
                // 90 degrees
                mOverlay.setCameraInfo(min, max, mCameraSource.getCameraFacing());
            } else {
                mOverlay.setCameraInfo(max, min, mCameraSource.getCameraFacing());
            }
            mOverlay.clear();
        }
        mStartRequested = false;
    }
}

@Override
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
    int width = 320;
    int height = 240;
    if (mCameraSource != null) {
        Size size = mCameraSource.getPreviewSize();
        if (size != null) {
            width = size.getWidth();
            height = size.getHeight();
        }
    }

    // Swap width and height sizes when in portrait, since it will be rotated 90 degrees
    if (isPortraitMode()) {
        int tmp = width;
        width = height;
        height = tmp;
    }

private boolean isPortraitMode() {
    int orientation = mContext.getResources().getConfiguration().orientation;
    if (orientation == Configuration.ORIENTATION_LANDSCAPE) {
        return false;
    }
    if (orientation == Configuration.ORIENTATION_PORTRAIT) {
        return true;
    }

    Log.d(TAG, "isPortraitMode returning false by default");
    return false;
}

这是来自官方的 Android Vision github page

【讨论】:

  • 感谢@Shanky.. 将检查此代码/链接并在此处更新结果
  • 根据上面的代码,我们必须显示相机预览,然后它才适用于表面支架。但在我的情况下,相机预览是错误的,相机在后台运行,并且通过服务活动连续运行,因此在我的代码中没有 SurfaceView 持有人。
【解决方案2】:

您需要查看 CameraSourcePreview 类文件。这是包含所有预览条件的文件。

这里是sn-p:

if (childHeight > layoutHeight) {
    childHeight = layoutHeight;
    childWidth = (int)(((float) layoutHeight / (float) height) * width);
}

所以,如果你删除或处理得当,你的问题是可以解决的。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-02-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-09-23
    • 2011-03-01
    • 2014-07-01
    相关资源
    最近更新 更多