我正在探索精彩的移动视觉apis,我正在研究Face Tracker示例,并寻找一个解决方案,我可以找出嘴是否开放。例如人在打呵欠。没有像face.getIsLeftEyeOpenProbability();
所以我想我需要找出左右口的x,y坐标找出差异并弄清楚鼠标是否打开。我不确定这是否有效。
但是,还有其他任何方法可以确定口是开口还是闭口?
答案 0 :(得分:2)
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 - 此代码将找到左右口的中心点坐标,并找出底口坐标和中心点坐标之间的差异。
答案 1 :(得分:1)
不幸的是,Mobile Vision API不支持张开检测。
答案 2 :(得分:1)
API确实可以跟踪口腔左侧,右侧和底部的面部标志:
https://developers.google.com/android/reference/com/google/android/gms/vision/face/Landmark
但不,API中没有明确的张开检测。
答案 3 :(得分:1)
我们可以使用uthLeftPosition,uthRightPosition和uthBottomPosition之间的角度检测嘴是否张开。
使用以下方法计算角度:
双浮子比率=(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");
}
答案 4 :(得分:0)
在每种情况下,计算左右嘴点之间的距离都无法正常工作,因为当用户离开相机时,该距离将比用户靠近相机时要短,因此没有标准来获得恒定的阈值以检测何时张开嘴。 我认为,更好的方法可以是计算嘴巴线的左->底部和右->底部之间的角度。当角度减小时,将描述张口事件。
我一直在尝试达到相同的目的,没有办法使用简单的方法来找到它。因此,我考虑了这个解决方案,并最终将其实施。