Я пишу некоторый код в Android, я должен сделать обнаружение лица с помощью camera2 API. Мой код основан на Android-Camera2-Api-Face-Recon образцов , и я не знаю, почему, но когда я использую face.getBound()
, возвращаемые значения не видны.
Это для студии Android, в JAVA этот код должен рисовать прямоугольник вокруг головы, и он распознает, что есть голова, но прямоугольник нарисован где угодно и не следует за головой.
private void process(CaptureResult result) {
Integer mode = result.get(CaptureResult.STATISTICS_FACE_DETECT_MODE);
Face[] faces = result.get(CaptureResult.STATISTICS_FACES);
mFaceDetectionMatrix=new Matrix();
if (faces != null && mode != null) {
if (faces.length ==1) {
for(int i = 0; i < faces.length; i++) {
if (faces[i].getScore() > 50) {
int left = faces[i].getBounds().left;
int top = faces[i].getBounds().top;
int right = faces[i].getBounds().right;
int bottom = faces[i].getBounds().bottom;
float points[] = {(float)bottom, (float)right, (float)top, (float)left};
Log.i("Test", "faces : " + faces.length + " , mode : " + mode + " left " + left + " top " + top + " right " + right);
Rect uRect = new Rect(left, top, right, bottom); //The function I'm supposed to use
//Rect uRect = new Rect(+2000-bottom, 1500-left, +1500-top, 3500-right) the function I'm using in order to fix this problem
Прямоугольник перемещается влево или вправо, когда голова движется вниз или вверх и наоборот. Как вы видите, я пытаюсь исправить ситуацию, и мне нужно полностью изменить входы в Rect.
Я хотел бы исправить эту проблему должным образом и понять, почему она не работает, и если я не могу, я хотел бы изменить константы, которые я ввел в Rect, чтобы иметь возможность использовать этот код на всех устройствах.
Есть предложения ?
Для контроля ориентации датчика я использую этот код:
int orientationOffset;
orientationOffset = characteristics.get(CameraCharacteristics.SENSOR_ORIENTATION);
Rect activeArraySizeRect = characteristics.get(CameraCharacteristics.SENSOR_INFO_ACTIVE_ARRAY_SIZE);
//Face Detection Matrix
//mFaceDetectionMatrix = new Matrix();
// TODO - I guess that is not enough if we have a landscape layout too...
mFaceDetectionMatrix.setRotate(orientationOffset);
Log.i("Test", "activeArraySizeRect1: (" + activeArraySizeRect + ") -> " + activeArraySizeRect.width() + ", " + activeArraySizeRect.height());
Log.i("Test", "activeArraySizeRect2: " + mPreviewSize.getWidth() + ", " + mPreviewSize.getHeight());
float s1 = mPreviewSize.getWidth() / (float)activeArraySizeRect.width();
float s2 = mPreviewSize.getHeight() / (float)activeArraySizeRect.height();
//float s1 = mOverlayView.getWidth();
//float s2 = mOverlayView.getHeight();
boolean mirror = true; // we always use front face camera
boolean weAreinPortrait = true;
mFaceDetectionMatrix.postScale(mirror ? -s1 : s1, s2);
//mFaceDetectionMatrix.postRotate(orientation);
if (mSwappedDimensions) {
mFaceDetectionMatrix.postTranslate(mPreviewSize.getHeight(), mPreviewSize.getWidth());
} else {
// TODO - ...
}
Это как ... прямоугольник в ландшафте, а голова в портрете.
Спасибо
[EDIT]
Я нашел способ это исправить! В классе OverlayView, в onDraw, я добавляю это:
canvas.scale(-1, 1, getWidth()/2, getHeight()/2);
и я изменил OverlayView в фрагменте_camera2_basic.xml при добавлении андроида: вращение = "90"
и теперь прямоугольник двигается так, как должен.
Это решило проблему, теперь, в зависимости от используемого устройства, прямоугольник не имеет одинакового положения.
Я изменил верхнюю, левую, правую и нижнюю части так:
int left = (int)((float)(faces[i].getBounds().left)/MGpix.getWidth()*mTextureView.getHeight());
int top = (int)((float)(faces[i].getBounds().top)/MGpix.getHeight()*mTextureView.getWidth());
int right = (int)((float)(faces[i].getBounds().right)/MGpix.getWidth()*mTextureView.getHeight());
int bottom =(int)((float)(faces[i].getBounds().bottom)/MGpix.getHeight()*mTextureView.getWidth());
MGpix совпадает с характеристиками.get (CameraCharacteristics.SENSOR_INFO_PIXEL_ARRAY_SIZE);
Теперь он близок к работе, но прямоугольник, в зависимости от устройства, либо вокруг головы, либо рядом, но он следует за головой, как и раньше.
Например, на Honor 5c, прямоугольник хорошо расположен, но с huawey p9 lite верхний левый угол прямоугольника находится на носу.
Есть идеи, чтобы это исправить?