【问题标题】:Android Mobile Vision API detect mouth is openAndroid Mobile Vision API 检测口是否打开
【发布时间】:2017-02-08 07:50:33
【问题描述】:

我正在探索出色的移动视觉 api,我正在研究 Face Tracker 示例并寻找一个可以确定嘴巴是否张开的解决方案。例如人在打哈欠。没有像face.getIsLeftEyeOpenProbability();这样的直接方式

所以我想我需要找出左右嘴的x,y坐标找出差异并弄清楚鼠标是否打开。我不确定这是否可行。

但是有没有其他方法可以判断嘴是张开还是闭上?

【问题讨论】:

    标签: android face-recognition android-vision


    【解决方案1】:

    Mobile Vision API 不直接支持嘴巴开/关检测。但是这段代码可能会对你有所帮助。我已经在我的设备上测试并使用了魅力。

     @Override
        public void draw(Canvas canvas) {
    
            Face face = mFace;
    
            if (face == null) {
                return;
            }
    
            if ((contains(face.getLandmarks(), 11) != 99)
                    && (contains(face.getLandmarks(), 5) != 99)
                    && (contains(face.getLandmarks(), 6) != 99)
                    ) {
    
                Log.i(TAG, "draw: Mouth Open >> found all the points");
    
                /**
                 * for bottom mouth
                 */
                int cBottomMouthX;
                int cBottomMouthY;
                if (FaceTrackerActivity.mIsFrontFacing) {
                    cBottomMouthX = (int) translateX(face.getLandmarks().get(contains(face.getLandmarks(), 0)).getPosition().x);
                    cBottomMouthY = (int) translateY(face.getLandmarks().get(contains(face.getLandmarks(), 0)).getPosition().y);
    
                    Log.i(TAG, "draw: Condition Bottom mouth >> cBottomMouthX >> " + cBottomMouthX + "    cBottomMouthY >> " + cBottomMouthY);
    
    
                } else {
                    cBottomMouthX = (int) translateX(face.getLandmarks().get(contains(face.getLandmarks(), 0)).getPosition().x);
                    cBottomMouthY = (int) translateY(face.getLandmarks().get(contains(face.getLandmarks(), 0)).getPosition().y);
                }
                canvas.drawCircle(cBottomMouthX, cBottomMouthY, 10, mPaint);
    
                /**
                 * for left mouth
                 */
                int cLeftMouthX;
                int cLeftMouthY;
                if (FaceTrackerActivity.mIsFrontFacing) {
                    cLeftMouthX = (int) translateX(face.getLandmarks().get(contains(face.getLandmarks(), 5)).getPosition().x);
                    cLeftMouthY = (int) translateY(face.getLandmarks().get(contains(face.getLandmarks(), 5)).getPosition().y);
    
                    Log.i(TAG, "draw: Condition LEft mouth >> cLeftMouthX >> " + cLeftMouthX + "    cLeftMouthY >> " + cLeftMouthY);
    
    
                } else {
                    cLeftMouthX = (int) translateX(face.getLandmarks().get(contains(face.getLandmarks(), 5)).getPosition().x);
                    cLeftMouthY = (int) translateY(face.getLandmarks().get(contains(face.getLandmarks(), 5)).getPosition().y);
                }
                canvas.drawCircle(cLeftMouthX, cLeftMouthY, 10, mPaint);
    
                /**
                 * for Right mouth
                 */
                int cRightMouthX;
                int cRightMouthY;
                if (FaceTrackerActivity.mIsFrontFacing) {
                    cRightMouthX = (int) translateX(face.getLandmarks().get(contains(face.getLandmarks(), 11)).getPosition().x);
                    cRightMouthY = (int) translateY(face.getLandmarks().get(contains(face.getLandmarks(), 11)).getPosition().y);
    
                    Log.i(TAG, "draw: Condition Right mouth >> cRightMouthX >> " + cRightMouthX + "    cRightMouthY >> " + cRightMouthY);
    
    
                } else {
                    cRightMouthX = (int) translateX(face.getLandmarks().get(contains(face.getLandmarks(), 11)).getPosition().x);
                    cRightMouthY = (int) translateY(face.getLandmarks().get(contains(face.getLandmarks(), 11)).getPosition().y);
                }
                canvas.drawCircle(cRightMouthX, cRightMouthY, 10, mPaint);
    
                float centerPointX = (cLeftMouthX + cRightMouthX) / 2;
                float centerPointY = ((cLeftMouthY + cRightMouthY) / 2) - 20;
    
                canvas.drawCircle(centerPointX, centerPointY, 10, mPaint);
    
                float differenceX = centerPointX - cBottomMouthX;
                float differenceY = centerPointY - cBottomMouthY;
    
                Log.i(TAG, "draw: difference X >> " + differenceX + "     Y >> " + differenceY);
    
                if (differenceY < (-60)) {
                    Log.i(TAG, "draw: difference - Mouth is OPENED ");
                } else {
                    Log.i(TAG, "draw: difference - Mouth is CLOSED ");
                }
             }
         }
    

    这是另一种方法。

    int contains(List<Landmark> list, int name) {
        for (int i = 0; i < list.size(); i++) {
            if (list.get(i).getType() == name) {
                return i;
            }
        }
        return 99;
    }
    

    P.S - 此代码将找到左右嘴的中心点坐标,并找到底部嘴坐标和中心点坐标之间的差异。

    【讨论】:

    • 你好@KulsDroid我可以知道你从哪里得到这个语句mIsFrontFacing方法。我在这里遇到错误.. if (FaceTrackerActivity.mIsFrontFacing) {
    【解决方案2】:

    我们可以使用mouthLeftPosition、mouthRightPosition 和mouthBottomPosition 之间的角度来检测嘴巴是否张开。

    计算角度:

    双倍浮动比率 = (AB * AB + AC * AC - BC * BC) /( 2 * AC * AB); 度数 = Math.acos(ratio)*(180/Math.PI);

    if (degree < (110)) {
      System.out.println("Mouth is open");
    }else {
      System.out.println("Mouth is close");
    }
    

    【讨论】:

    • 我知道这已经很老了,但是.. 什么?这看起来真的很有帮助,但我不知道 AB、AC、BC 代表什么。如果您看到这一点,如果您在编辑时进行了一些澄清,那就太棒了。
    • 对于其他找到此内容的人。这是一个非常好的细分,我能够通过计算由嘴的 3 个点形成的三角形上的角度来获得非常可靠的嘴检测。 geeksforgeeks.org/find-angles-given-triangle
    【解决方案3】:

    很遗憾,Mobile Vision API 不支持张嘴检测。

    【讨论】:

      【解决方案4】:

      该 API 确实允许跟踪嘴巴左侧、右侧和底部的面部标志:

      https://developers.google.com/android/reference/com/google/android/gms/vision/face/Landmark

      但是不,API 中没有明确的张嘴检测。

      【讨论】:

      • 那么替代解决方案是什么?
      【解决方案5】:

      计算左右嘴点之间的距离并不是在每种情况下都适用,因为当用户远离相机时,这个距离会比用户靠近相机时更短,因此没有标准来获得用于检测嘴巴何时张开的恒定阈值。 我认为,更好的方法是计算左-> 下和右-> 嘴线之间的角度。当角度减小时,它会描绘一个张嘴事件。

      我一直在尝试实现相同的目标,但无法使用简单的方法找到它。所以,我考虑了这个解决方案,并将在我的最终实施它。

      【讨论】:

      • 这不是问题的答案,您必须在评论部分发布。
      猜你喜欢
      • 1970-01-01
      • 2017-08-30
      • 1970-01-01
      • 2017-12-30
      • 1970-01-01
      • 2017-10-21
      • 2017-07-14
      • 2019-08-04
      • 1970-01-01
      相关资源
      最近更新 更多