Сохранение изображения обнаруженного лица в реальном времени (отслеживание лиц) с помощью библиотеки android-vision

Для моей университетской диссертации мне нужна программа для Android, которая может обнаруживать и распознавать лица в реальном времени. Я прочитал о библиотеке android-vision и протестировал код примера.

https://github.com/googlesamples/android-vision/tree/master/visionSamples/FaceTracker/app/src/main/java/com/google/android/gms/samples/vision/face/facetracker.

Измененный код:

package com.google.android.gms.samples.vision.face.facetracker;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.os.AsyncTask;
import android.os.Environment;
import android.util.Log;
import android.widget.Toast;

import com.google.android.gms.samples.vision.face.facetracker.ui.camera.GraphicOverlay;
import com.google.android.gms.vision.face.Face;

import java.io.ByteArrayOutputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.net.Socket;
import java.text.SimpleDateFormat;
import java.util.Date;

/**
 * Graphic instance for rendering face position, orientation, and landmarks within an associated
 * graphic overlay view.
 */
class FaceGraphic extends GraphicOverlay.Graphic
{
    private static final float FACE_POSITION_RADIUS = 10.0f;
    private static final float ID_TEXT_SIZE = 40.0f;
    private static final float ID_Y_OFFSET = 50.0f;
    private static final float ID_X_OFFSET = -50.0f;
    private static final float BOX_STROKE_WIDTH = 5.0f;

    public Canvas canvas1;
    public Face face;
    int i =0;
    int flag = 0;

    private static final int COLOR_CHOICES[] = {
        Color.BLUE,
        Color.CYAN,
        Color.GREEN,
        Color.MAGENTA,
        Color.RED,
        Color.WHITE,
        Color.YELLOW
    };
    private static int mCurrentColorIndex = 0;

    private Paint mFacePositionPaint;
    private Paint mIdPaint;
    private Paint mBoxPaint;

    private volatile Face mFace;
    private int mFaceId;
    private float mFaceHappiness;
    public Bitmap myBitmap ;
    FaceGraphic(GraphicOverlay overlay)
    {
        super(overlay);

        mCurrentColorIndex = (mCurrentColorIndex + 1) % COLOR_CHOICES.length;
        final int selectedColor = COLOR_CHOICES[mCurrentColorIndex];

        mFacePositionPaint = new Paint();
        mFacePositionPaint.setColor(selectedColor);

        mIdPaint = new Paint();
        mIdPaint.setColor(selectedColor);
        mIdPaint.setTextSize(ID_TEXT_SIZE);

        mBoxPaint = new Paint();
        mBoxPaint.setColor(selectedColor);
        mBoxPaint.setStyle(Paint.Style.STROKE);
        mBoxPaint.setStrokeWidth(BOX_STROKE_WIDTH);
    }

    void setId(int id)
    {
        mFaceId = id;
        flag = 1;
    }


    /**
     * Updates the face instance from the detection of the most recent frame.  Invalidates the
     * relevant portions of the overlay to trigger a redraw.
     */
    void updateFace(Face face)
    {
        mFace = face;
        postInvalidate();
    }

    /**
     * Draws the face annotations for position on the supplied canvas.
     */
    @Override
    public void draw(Canvas canvas)
    {
        face = mFace;
        if (face == null)
        {
            return;
        }

        // Draws a circle at the position of the detected face, with the face's track id below.
        float x = translateX(face.getPosition().x + face.getWidth() / 2);
        float y = translateY(face.getPosition().y + face.getHeight() / 2);
 //       canvas.drawCircle(x, y, FACE_POSITION_RADIUS, mFacePositionPaint);
        canvas.drawText("id: " + mFaceId, x + ID_X_OFFSET, y + ID_Y_OFFSET, mIdPaint);
  //      canvas.drawText("happiness: " + String.format("%.2f", face.getIsSmilingProbability()), x - ID_X_OFFSET, y - ID_Y_OFFSET, mIdPaint);
  //      canvas.drawText("right eye: " + String.format("%.2f", face.getIsRightEyeOpenProbability()), x + ID_X_OFFSET * 2, y + ID_Y_OFFSET * 2, mIdPaint);
  //      canvas.drawText("left eye: " + String.format("%.2f", face.getIsLeftEyeOpenProbability()), x - ID_X_OFFSET*2, y - ID_Y_OFFSET*2, mIdPaint);

        // Draws a bounding box around the face.
        float xOffset = scaleX(face.getWidth() / 2.0f);
        float yOffset = scaleY(face.getHeight() / 2.0f);
        float left = x - xOffset;
        float top = y - yOffset;
        float right = x + xOffset;
        float bottom = y + yOffset;
        canvas.drawRect(left, top, right, bottom, mBoxPaint);

        Log.d("MyTag", "hello "+i);
        i++;

        if (flag == 1)
        {
            flag = 0;
            canvas1=canvas;
            // send face image to server for recognition
            new MyAsyncTask().execute("ppppp");

        }
    }


    class MyAsyncTask extends AsyncTask<String, Void, String>
    {
        private Context context;

        public MyAsyncTask()
        {
            // TODO Auto-generated constructor stub
            //context = applicationContext;
        }

        protected String doInBackground(String... params)
        {
            try
            {

                Log.d("MyTag", "face.getWidth() "+face.getWidth());
                Bitmap temp_bitmap = Bitmap.createBitmap((int)face.getWidth(), (int)face.getHeight(), Bitmap.Config.RGB_565);
                canvas1.setBitmap(temp_bitmap);


            }
            catch (Exception e)
            {
                Log.e("MyTag", "I got an error", e);
                e.printStackTrace();
            }
            Log.d("MyTag", "doInBackground");
            return null;
        }

        protected void onPostExecute(String result) {
            Log.d("MyTag", "onPostExecute " + result);
            // tv2.setText(s);

        }

    }

}

Это дает мне эту ошибку:

12-16 03:08:00.310 22926-23044/com.google.android.gms.samples.vision.face.facetracker E/MyTag: I got an error
                                                                                               java.lang.UnsupportedOperationException
                                                                                                   at android.view.HardwareCanvas.setBitmap(HardwareCanvas.java:39)
                                                                                                   at com.google.android.gms.samples.vision.face.facetracker.FaceGraphic$MyAsyncTask.doInBackground(FaceGraphic.java:175)
                                                                                                   at com.google.android.gms.samples.vision.face.facetracker.FaceGraphic$MyAsyncTask.doInBackground(FaceGraphic.java:158)

Этот код может определять лицо в реальном времени. Для распознавания я планирую использовать "JavaCV" https://github.com/bytedeco/javacv. Если я могу запечатлеть лицо в растровом изображении, я могу сохранить его в изображении .jpg, и тогда я смогу его распознать. Не могли бы вы посоветовать, как сохранить обнаруженное лицо. Спасибо.


person user1850484    schedule 15.12.2017    source источник
comment
У меня твоя проблема. Вы нашли какое-нибудь решение ??   -  person mohamad ali gharat    schedule 02.02.2018
comment
нет. Ищу ответ.   -  person user1850484    schedule 03.02.2018
comment
ты нашел ответ?   -  person Uma Achanta    schedule 04.07.2018


Ответы (1)


TL; DR: захватить кадр, обработать его, затем сохранить / экспортировать.

Из источника

@Override
public void setBitmap(Bitmap bitmap) {
    throw new UnsupportedOperationException();
}

Это означает, что Canvas не может обрабатывать метод setBitmap(Bitmap bitmap).

У вас есть несколько проблем с тем, что вы делаете.

Во-первых: множество AsynkTask (ов), и многие из них бесполезны / избыточны

Если вы используете классы com.google.android.gms.vision.*, вы, вероятно, получаете около 30 событий в секунду. Когда происходит событие, захваченный кадр почти наверняка отличается от оцениваемого. Вы соревнуетесь со своими условиями.

Во-вторых: использование холста для установки растрового изображения

Всегда, используя класс, проверяйте его документацию и предков и, наконец, его реализацию.

ImageView будет работать так, как вы хотите. Получив Bitmap, затем установив его. Все условия гонок будут обрабатываться ОС ‹, а избыточные запросы будут отброшены Главный лупер

Ну наконец то

Если вам, возможно, нужно «сфотографировать, когда кто-то улыбается с закрытыми глазами», тогда вам нужно перевернуть свою логику. Используйте источник для создания кадров. Затем обработайте фрейм и, если он соответствует вашим критериям, сохраните его.

Этот проект codelabs делает почти то, что вы хотите, и он объясняет его детали очень хорошо

person Bonatti    schedule 06.12.2018