GithubHelp home page GithubHelp logo

facevision-wanted-detector-app's Introduction

FaceVision

Logo_FaceVision

IoT Project

Android + ESP32 + SERVER

The FaceVision app is a technological tool that uses machine learning (ML) and the mobile device with the Android operating system and allows it to identify wanted persons. The app compares the faces of the wanted persons in the database to the faces in the current frame from the camera and when matched, the name and additional information about the suspect are displayed and in addition the system shows its place on the map. The system offers real-time identification of wanted persons, and can be used by the police, security personnel and the general public. This makes the app an effective tool for preventing crime and apprehending suspects. Apart from using the phone camera, there is also the option of connecting an external camera that I built based on the esp32 microcontroller. This camera can be used to capture faces even without the phone camera being open. The frames taken with this external camera are transmitted to the server and from there for decoding in the application using a special protocol, and upon identification of the requested information will be displayed on your device.

מחלקות (Classes)

RecognitionApi

הגדרת משתנים ואובייקטים

    private FaceDetector detector; // אחראי ללכידת הפנים (ML Kit)
    Interpreter tfLite; // אחראי לפעולות הפענוח של הפנים (TensorFlow Lite)
    boolean start = true;
    private final HashMap<String, SimilarityClassifier.Recognition> registered = new HashMap<>(); //הפנים השמורות
    List<FaceDetectedEvent> listeners;
    FaceDetectedEvent faceDetectedEvent; // מאזין לזיהוי הפנים בפריים
    ViewModelStoreOwner owner;
    int[] intValues; //מערך של int חלק מתהליך זיהוי הפנים
    int inputSize = 112;  //גודל המודל
    boolean isModelQuantized = false;
    float[][] embeedings; //שמירת וקטורי הפנים שנלכדו
    float[][] emb;
    float IMAGE_MEAN = 128.0f;
    float IMAGE_STD = 128.0f;
    int OUTPUT_SIZE = 192; //Output size of model
    String modelFile = "mobile_face_net.tflite"; //model name
    Context activityContext;
    Gson gson;

פונקציות

    public  void detect(Bitmap bitmap) {


        if (bitmap == null) {
            return;
        }

        InputImage image = InputImage.fromBitmap(bitmap, 0);


        Task<List<Face>> result =
                detector.process(image)
                        .addOnSuccessListener(
                                new OnSuccessListener<List<Face>>() {
                                    @Override 
                                    public void onSuccess(List<Face> faces) {
                                        if(faces.size()!=0)
                                        {
                                            Face face = faces.get(0);
                                            RectF rect = new RectF(face.getBoundingBox());
                                            Bitmap cropped_face = getCropBitmapByCPU(bitmap, rect);

                                            try {

                                                recognizeImage(cropped_face);

                                            } catch (Exception e) {
                                                e.printStackTrace();
                                                Log.d("RecognitionApi", "Error" + e.getMessage());
                                            }



                                        }
                                    }
                                })


                        .addOnCompleteListener(new OnCompleteListener<List<Face>>() {
                            @Override
                            public void onComplete(@NonNull Task<List<Face>> task) {
                                // detector.close();
                            }
                        })
                        .addOnFailureListener(
                                new OnFailureListener() {
                                    @Override
                                    public void onFailure(@NonNull Exception e) {
                                        // Task failed with an exception
                                        // ...
                                    }
                                });
    }

    
    
    public  void detect(ImageProxy imageProxy)
    {

        InputImage image = null;


        if(imageProxy.getImage()==null)
        {
            return;
        }


        @SuppressLint({"UnsafeExperimentalUsageError", "UnsafeOptInUsageError"})
        // Camera Feed-->Analyzer-->ImageProxy-->mediaImage-->InputImage(needed for ML kit face detection)

        Image mediaImage = imageProxy.getImage();


        if (mediaImage != null) {
            image = InputImage.fromMediaImage(mediaImage, imageProxy.getImageInfo().getRotationDegrees());
            System.out.println("Rotation " + imageProxy.getImageInfo().getRotationDegrees());
        }


        Bitmap bitmap = toBitmap(mediaImage);

        Task<List<Face>> result =
                detector.process(image)
                        .addOnSuccessListener(
                                new OnSuccessListener<List<Face>>() {
                                    @Override
                                    public void onSuccess(List<Face> faces) {
                                        if(faces.size()!=0)
                                        {
                                            Face face = faces.get(0);



                                            int rot = imageProxy.getImageInfo().getRotationDegrees();

                                            //Adjust orientation of Face
                                            Bitmap frame_bmp1 = rotateBitmap(bitmap, rot, false, false);


                                            //Get bounding box of face
                                            RectF boundingBox = new RectF(face.getBoundingBox());



                                            //Crop out bounding box from whole Bitmap(image)
                                            Bitmap cropped_face = getCropBitmapByCPU(frame_bmp1, boundingBox);



                                            Bitmap scaled = getResizedBitmap(cropped_face, 112, 112);



                                            recognizeImage(scaled);




                                        }
                                    }
                                })


                        .addOnCompleteListener(new OnCompleteListener<List<Face>>() {
                            @Override
                            public void onComplete(@NonNull Task<List<Face>> task) {
                                // detector.close();
                                imageProxy.close(); //v.important to acquire next frame for analysis
                            }
                        })
                        .addOnFailureListener(
                                new OnFailureListener() {
                                    @Override
                                    public void onFailure(@NonNull Exception e) {
                                        // Task failed with an exception
                                        // ...
                                    }
                                });






    }

    public  void initializeFaceDetector() {
        FaceDetectorOptions highAccuracyOpts =
                new FaceDetectorOptions.Builder()
                        .setPerformanceMode(FaceDetectorOptions.PERFORMANCE_MODE_ACCURATE)
                        .setContourMode(FaceDetectorOptions.CONTOUR_MODE_ALL)

                        .build();
        detector = FaceDetection.getClient(highAccuracyOpts);

    }
    public static Bitmap getCropBitmapByCPU(Bitmap source, RectF cropRectF) {
        Bitmap resultBitmap = Bitmap.createBitmap((int) cropRectF.width(),
                (int) cropRectF.height(), Bitmap.Config.ARGB_8888);
        Canvas cavas = new Canvas(resultBitmap);

        // draw background
        Paint paint = new Paint(Paint.FILTER_BITMAP_FLAG);
        paint.setColor(Color.WHITE);
        cavas.drawRect(//from  w w  w. ja v  a  2s. c  om
                new RectF(0, 0, cropRectF.width(), cropRectF.height()),
                paint);

        Matrix matrix = new Matrix();
        matrix.postTranslate(-cropRectF.left, -cropRectF.top);

        cavas.drawBitmap(source, matrix, paint);

        if (source != null && !source.isRecycled()) {
            source.recycle();
        }

        return resultBitmap;
    }
    public void loadModel() {
        try {

            tfLite = new Interpreter(loadModelFile (activityContext  , modelFile));
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    //----------------------------------------

    private MappedByteBuffer loadModelFile(Context activity, String MODEL_FILE) throws IOException {
        AssetManager assetManager = activity.getAssets();
        AssetFileDescriptor fileDescriptor = assetManager.openFd(MODEL_FILE);
        FileInputStream inputStream = new FileInputStream(fileDescriptor.getFileDescriptor());
        FileChannel fileChannel = inputStream.getChannel();
        long startOffset = fileDescriptor.getStartOffset();
        long declaredLength = fileDescriptor.getDeclaredLength();
        return fileChannel.map(FileChannel.MapMode.READ_ONLY, startOffset, declaredLength);
    }
    public void recognizeImage(final Bitmap bitmap) {


        Log.d("api", "recognizeImage: ");
        FaceRecViewModel.bitmap = bitmap;

        //Create ByteBuffer to store normalized image

        ByteBuffer imgData = ByteBuffer.allocateDirect(1 * inputSize * inputSize * 3 * 4);

        imgData.order(ByteOrder.nativeOrder());

        intValues = new int[inputSize * inputSize];

        //get pixel values from Bitmap to normalize

        bitmap.getPixels(intValues, 0, bitmap.getWidth(), 0, 0, bitmap.getWidth(), bitmap.getHeight());


        imgData.rewind();

        for (int i = 0; i < inputSize; ++i) {
            for (int j = 0; j < inputSize; ++j) {
                int pixelValue = intValues[i * inputSize + j];
                if (isModelQuantized) {
                    // Quantized model
                    imgData.put((byte) ((pixelValue >> 16) & 0xFF));
                    imgData.put((byte) ((pixelValue >> 8) & 0xFF));
                    imgData.put((byte) (pixelValue & 0xFF));
                } else { // Float model
                    imgData.putFloat((((pixelValue >> 16) & 0xFF) - IMAGE_MEAN) / IMAGE_STD);
                    imgData.putFloat((((pixelValue >> 8) & 0xFF) - IMAGE_MEAN) / IMAGE_STD);
                    imgData.putFloat(((pixelValue & 0xFF) - IMAGE_MEAN) / IMAGE_STD);

                }
            }
        }
        //imgData is input to our model
        Object[] inputArray = {imgData};

        Map<Integer, Object> outputMap = new HashMap<>();


        embeedings = new float[1][OUTPUT_SIZE]; //output of model will be stored in this variable




        outputMap.put(0, embeedings);

        tfLite.runForMultipleInputsOutputs(inputArray, outputMap); //Run model


        float distance = Float.MAX_VALUE;
        String id = "0";
        String label = "?";

        FaceRecViewModel.Embeddings = embeedings;

        //wantedAddedEvent.onWantedAdded(embeedings[0]);

        //Compare new face with saved Faces.
        if (registered.size() > 0) {

            final Pair<String, Float> nearest = findNearest(embeedings[0]);//Find closest matching face

            if (nearest != null) {

                distance = nearest.second;

                final String name = nearest.first;
                label = name;
                distance = nearest.second;



                if(distance<1.000f) {//If distance between Closest found face is more than 1.000 ,then output UNKNOWN face.
                    //  viewModel.setName(String.valueOf(name));
                    Log.d("faceD", "aaaa");
                   // viewModel.setName(String.valueOf(name));


                    faceDetectedEvent.onFaceDetected(bitmap,name, accuracyOfDetection(distance));




                }

                else{
                    faceDetectedEvent.onFaceDetected(bitmap,"UNKNOWN", accuracyOfDetection(distance));
                    //viewModel.setName("UNKNOWN");
                    Log.d("faceD", "UNKNOWN");

                }


            }
        }


    }
    private Pair<String, Float> findNearest(float[] emb) {

        Pair<String, Float> ret = null;
        for (Map.Entry<String, SimilarityClassifier.Recognition> entry : registered.entrySet()) {

            final String name = entry.getKey();
            final float[] knownEmb = ((float[][]) entry.getValue().getExtra())[0];



            FaceRecViewModel.Embeddings = embeedings;



            float distance = 0;
            for (int i = 0; i < emb.length; i++) {
                float diff = emb[i] - knownEmb[i];
                distance += diff*diff;
            }
            distance = (float) Math.sqrt(distance);
            if (ret == null || distance < ret.second) {
                ret = new Pair<>(name, distance);
            }
        }

        return ret;

    }
    public Bitmap toBitmap(Image image) {

        byte[] nv21 = YUV_420_888toNV21(image);


        YuvImage yuvImage = new YuvImage(nv21, ImageFormat.NV21, image.getWidth(), image.getHeight(), null);

        ByteArrayOutputStream out = new ByteArrayOutputStream();
        yuvImage.compressToJpeg(new Rect(0, 0, yuvImage.getWidth(), yuvImage.getHeight()), 75, out);

        byte[] imageBytes = out.toByteArray();
        //System.out.println("bytes"+ Arrays.toString(imageBytes));

        //System.out.println("FORMAT"+image.getFormat());

        return BitmapFactory.decodeByteArray(imageBytes, 0, imageBytes.length);
    }

    //----------------------------------------

    /**
     * <h1>YUV_420_888toNV21</h1>
     * <p>מעביר את התמונה לפורמט NV21</p>
     * @param image
     */
    private static byte[] YUV_420_888toNV21(Image image) {

        int width = image.getWidth();
        int height = image.getHeight();
        int ySize = width * height;
        int uvSize = width * height / 4;

        byte[] nv21 = new byte[ySize + uvSize * 2];

        ByteBuffer yBuffer = image.getPlanes()[0].getBuffer(); // Y
        ByteBuffer uBuffer = image.getPlanes()[1].getBuffer(); // U
        ByteBuffer vBuffer = image.getPlanes()[2].getBuffer(); // V

        int rowStride = image.getPlanes()[0].getRowStride();
        assert (image.getPlanes()[0].getPixelStride() == 1);

        int pos = 0;

        if (rowStride == width) {
            yBuffer.get(nv21, 0, ySize);
            pos += ySize;
        } else {
            long yBufferPos = -rowStride;
            for (; pos < ySize; pos += width) {
                yBufferPos += rowStride;
                yBuffer.position((int) yBufferPos);
                yBuffer.get(nv21, pos, width);
            }
        }

        rowStride = image.getPlanes()[2].getRowStride();
        int pixelStride = image.getPlanes()[2].getPixelStride();

        assert (rowStride == image.getPlanes()[1].getRowStride());
        assert (pixelStride == image.getPlanes()[1].getPixelStride());

        if (pixelStride == 2 && rowStride == width && uBuffer.get(0) == vBuffer.get(1)) {
            // maybe V an U planes overlap as per NV21, which means vBuffer[1] is alias of uBuffer[0]
            byte savePixel = vBuffer.get(1);
            try {
                vBuffer.put(1, (byte) ~savePixel);
                if (uBuffer.get(0) == (byte) ~savePixel) {
                    vBuffer.put(1, savePixel);
                    vBuffer.position(0);
                    uBuffer.position(0);
                    vBuffer.get(nv21, ySize, 1);
                    uBuffer.get(nv21, ySize + 1, uBuffer.remaining());

                    return nv21; // shortcut
                }
            } catch (ReadOnlyBufferException ex) {
                // unfortunately, we cannot check if vBuffer and uBuffer overlap
            }

            // unfortunately, the check failed. We must save U and V pixel by pixel
            vBuffer.put(1, savePixel);
        }

        // other optimizations could check if (pixelStride == 1) or (pixelStride == 2),
        // but performance gain would be less significant

        for (int row = 0; row < height / 2; row++) {
            for (int col = 0; col < width / 2; col++) {
                int vuPos = col * pixelStride + row * rowStride;
                nv21[pos++] = vBuffer.get(vuPos);
                nv21[pos++] = uBuffer.get(vuPos);
            }
        }

        return nv21;
    }
   public void setWantedList(ArrayList<Wanted> wanted){


        for (Wanted w : wanted) {
            SimilarityClassifier.Recognition rec = new SimilarityClassifier.Recognition("", "", 0.0f);
            emb = gson.fromJson(w.getId(), FaceRecViewModel.typeToken.getType());
            Object obj = emb;
            rec.setExtra(obj);
            this.registered.put(w.getFirstName() +" "+ w.getLastName(), rec);
        }
    }

    public void setFaceDetectedEvent(FaceDetectedEvent faceDetectedEvent){
        this.faceDetectedEvent = faceDetectedEvent;
        }
    public String accuracyOfDetection(float distance) {
        String result = "";

        if (distance < 0.5f)
            result = "High";

        else if (distance >= 0.5f && distance < 0.8f)
            result = "Medium";

        else if (distance >= 0.8f && distance < 1f)
            result = "Low";

        else result = "No Match";

        return result;

    }
    private static Bitmap rotateBitmap(
            Bitmap bitmap, int rotationDegrees, boolean flipX, boolean flipY) {
        Matrix matrix = new Matrix();

        // Rotate the image back to straight.
        matrix.postRotate(rotationDegrees);

        // Mirror the image along the X or Y axis.
        matrix.postScale(flipX ? -1.0f : 1.0f, flipY ? -1.0f : 1.0f);
        Bitmap rotatedBitmap =
                Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true);

        // Recycle the old bitmap if it has changed.
        if (rotatedBitmap != bitmap) {
            bitmap.recycle();
        }
        return rotatedBitmap;
    }


    //----------------------------------------


    /**
     * Gets resized bitmap.
     *
     * @param bm        the bm
     * @param newWidth  the new width
     * @param newHeight the new height
     * @return the resized bitmap
     */
    public Bitmap getResizedBitmap(Bitmap bm, int newWidth, int newHeight) {
        int width = bm.getWidth();
        int height = bm.getHeight();
        float scaleWidth = ((float) newWidth) / width;
        float scaleHeight = ((float) newHeight) / height;
        // CREATE A MATRIX FOR THE MANIPULATION
        Matrix matrix = new Matrix();
        // RESIZE THE BIT MAP
        matrix.postScale(scaleWidth, scaleHeight);

        // "RECREATE" THE NEW BITMAP
        Bitmap resizedBitmap = Bitmap.createBitmap(
                bm, 0, 0, width, height, matrix, false);
        bm.recycle();
        return resizedBitmap;
    }

מאיזינים (Intefraces)

FaceDetectedEvent


DownloadBitmapApi

הגדרת משתנים ואובייקטים

    private boolean isRunning = true;
    private String url;
    public Bitmap bitmap;
    private final Context context;
    int count = 0;
    ImageTakenEvent imageTakenEvent;

פונקציות

public void start() {

        isRunning = true;

        if (url == null || !isRunning) {
            Log.d("Download Bitmap", "url is null or already running");
            return;
        }
        Log.d("Download Bitmap", "run: " + bitmap);

        isRunning = true;
        new Thread(new Runnable() {
            @Override
            public void run() {
                Looper.prepare();



                while (isRunning) {

                    count++;

                    try {
                        bitmap = getBitmapFromURL(url + "?" + System.currentTimeMillis());


                        new Handler(Looper.getMainLooper()).post(new Runnable() {
                            @Override
                            public void run() {
                                imageTakenEvent.onImageTaken(bitmap);
                              //  Log.d("Download Bitmap", "run: " + bitmap);
                                Log.d("Download Bitmap", "run: " + count);

                            }
                        });

                        Thread.sleep(100);
                    } catch (InterruptedException ie) {
                        ie.printStackTrace();
                    }
                }
            }
        }).start();
    }


public void stop(){
        isRunning = false;
        }
    public Bitmap getBitmapFromURL(String src) {
        try {
            URL url = new URL(src);
            HttpURLConnection connection = (HttpURLConnection) url.openConnection();
            connection.setDoInput(true);
            connection.connect();
            InputStream input = connection.getInputStream();
            return BitmapFactory.decodeStream(input);
        } catch (IOException e) {
            e.printStackTrace();

            return null;
        }
    }

מאיזינים (Intefraces)

ImageTakenEvent


Repo

מחלקה זו אחראית על התקשורת בין מאגר הנתונים בFirebase לאפליקציה, ומאפשרת עדכון נתונים באופן דינאמי.

הגדרת משתנים ואובייקטים

    static Repo instance;
    private final ArrayList<Wanted> wanteds = new ArrayList<>();
    private final ArrayList<User> users = new ArrayList<>();
    private final MutableLiveData<ArrayList<Wanted>> wanted = new MutableLiveData<>(); // wanted list
    private final MutableLiveData<ArrayList<User>> user = new MutableLiveData<>();
    static final DatabaseReference wantedRef = FirebaseDatabase.getInstance().getReference("wanted");

פונקציות

    public static Repo getInstance() {
        if (instance == null) {
            instance = new Repo();
        }
        return instance;
    }
    
    public MutableLiveData<ArrayList<Wanted>> getWanteds() {

        if (wanteds.size() == 0) {
            retriveWanted();
        }

        wanted.setValue(wanteds);
        return wanted;

    }

    public MutableLiveData<ArrayList<User>> getUsers() {

        if (users.size() == 0) {
            retrieveUser();
        }

        user.setValue(users);
        return user;

    }





    public void retriveWanted() {

        DatabaseReference database = FirebaseDatabase.getInstance().getReference("Wanted");
        database.addValueEventListener(new ValueEventListener() {
            @Override
            public void onDataChange(@NonNull DataSnapshot snapshot) {
                wanted.getValue().clear();
                for (DataSnapshot ds : snapshot.getChildren()) {
                    wanteds.add(ds.getValue(Wanted.class));
                }

                wanted.setValue(null);
                wanted.postValue(wanteds);

            }

            @Override
            public void onCancelled(@NonNull DatabaseError error) {

            }
        });

    }


    public void retrieveUser(){

        DatabaseReference database = FirebaseDatabase.getInstance().getReference("Users");

        database.addValueEventListener(new ValueEventListener() {
            @Override
            public void onDataChange(@NonNull DataSnapshot snapshot) {

                user.getValue().clear();

                for (DataSnapshot ds : snapshot.getChildren()) {
                    users.add(ds.getValue(User.class));
                }

                user.setValue(null);
                user.postValue(users);

            }

            @Override
            public void onCancelled(@NonNull DatabaseError error) {

            }
        });

    }

תצוגה של שמירת הנתונים בפיירביס כקובץ Json

image

{
  "Users": {
    "-N-IMudKi-oFy9FRHisJ": {
      "email": "[email protected]",
      "password": "yyyyyy",
      "uid": "-N-IMudKi-oFy9FRHisJ"
    },
    "-N-IUGnR8YYSBJd1z1av": {
      "email": "[email protected]",
      "password": "yyyyyyy",
      "uid": "-N-IUGnR8YYSBJd1z1av"
    }
  },
  "Wanted": {
    "-N-DWhYgaWtkqU6Ssekb": {
      "firstName": "b",
      "id": "[[-0.0010410135,0.009628831,0.010786182,-0.0054620407,-0.017342247,0.16972956,0.035113342,0.12557173,-0.05729674,-0.23139378,-0.0011715854,0.0076675173,-0.0060608457,0.021590777,0.0037774534,0.06945441,-2.522286E-4,0.008889398,-0.0022686548,0.0012244228,-0.28658593,0.04478087,0.06483153,-0.0019388105,-0.005111154,0.011119399,-0.012869898,0.07635839,-0.07545111,0.003345836,-0.0045659943,-0.0779627,0.14756562,0.0030033942,-0.03442563,0.049341083,-0.06983834,-0.006458608,0.0032271834,0.15341885,9.31929E-4,0.0036573492,0.004183538,-4.8961537E-4,-0.007381257,-0.013672632,-0.0576776,0.13247061,0.0027207863,-0.022482777,0.041603774,-0.0031791043,0.15681735,-6.877006E-4,0.042630084,-0.008161148,-0.16617066,-0.0023209415,-0.013752797,0.023938121,0.0369629,0.0043679746,0.06325639,-0.039085478,-2.327944E-4,-0.16532621,9.510836E-4,-0.01461484,-0.0028614285,3.8600856E-4,-0.009465449,0.16616216,-0.13870268,0.0061112437,0.08317331,0.009896848,0.0019666047,0.0044759843,-0.092623666,-0.017751034,0.0024296262,0.031452626,-0.0076886266,0.24939343,-0.07279492,0.002314762,-0.00441885,0.1271898,0.017952092,-0.044802375,0.12992984,8.866098E-4,-0.0050643967,-0.015138161,-0.07330176,-0.13375889,0.048159875,0.0888026,-0.0010018667,-0.005603576,0.0016471365,4.709781E-6,-0.0069411206,-3.6836325E-4,-0.010652501,0.0013076725,-0.10219801,-4.5381248E-4,0.008744307,-0.0076356796,-0.051288262,0.003241733,0.0031532908,-0.28951693,0.011590097,-0.0073560756,-0.01427289,-0.016451342,-0.09925304,0.1354679,0.015786558,-0.018121727,0.012385498,-7.51372E-4,0.0037261806,0.001955275,0.0048412336,0.0042819185,-0.0034855728,0.19582444,0.0035607575,-0.005586806,0.0023442877,-0.018662522,0.12461485,-0.009434344,-0.07167587,0.0022182574,0.011361994,0.01909742,-0.003204724,0.0016544717,0.0068640774,0.23292816,0.16324323,-0.071317345,0.013641624,0.0023167657,-6.322562E-4,-0.00698097,0.002779571,0.040855035,0.07781138,-6.1080226E-4,-0.003179328,-0.0113768075,-0.008758626,0.023726327,-0.0066552125,0.004433571,-0.020477917,-0.0050954404,-0.008487688,0.0022544258,-5.7189533E-5,0.010942446,0.013927165,-0.04511513,-0.005983547,0.0015417954,0.27572143,0.10947642,7.0208334E-5,0.05793188,0.016310148,0.006158329,-0.10900652,-0.019061118,-0.0020322332,0.001597081,-0.07266038,-0.06417121,0.007374468,-0.0050402964,-0.08927689,0.03624378,-0.013405281,0.09158981,-0.011056186,0.026418133,-0.032307833,-0.0063484567]]",
      "imageUrl": "https://firebasestorage.googleapis.com/v0/b/facevision-mvvm.appspot.com/o/images%2F-N-DWhYgaWtkqU6Ssekb?alt=media&token=8ce80afd-dd43-4da9-bc6e-7b0e171077a4",
      "key": "-N-DWhYgaWtkqU6Ssekb",
      "lastName": "",
      "location": {
        "latitude": 32.0923393,
        "longitude": 34.9722727
      }
    },
    "-N-DXUgW5zPvmKc9akgN": {
      "firstName": "yoni",
      "id": "[[-0.013441408,0.026486065,0.008166146,-0.0065202746,-0.061931167,0.09741596,-0.09463319,-0.037456434,-0.03962274,-0.012304927,-0.027717628,0.0058319345,-0.008313347,0.023376876,-0.0036113793,-0.03789333,-0.025476761,-0.011577417,-6.766282E-5,0.005754016,-0.15575974,0.103555135,-0.01366982,0.015013042,-0.057849202,0.012086764,-0.047271363,0.10145963,0.16120847,-0.12074202,-0.0144114345,0.17240885,0.049797244,3.7592117E-4,-0.009133127,0.046619564,-0.009602987,-0.028868442,0.0010256692,0.06772082,0.0074122758,0.0056303665,0.02315589,-0.018348983,0.012992912,-0.05166491,-0.10818403,-0.058490284,-0.016850613,0.039827745,-0.11021288,-0.007353817,-0.24465373,-0.0025254176,-0.077699095,0.006147024,0.1936563,0.0048825275,-0.12100764,0.03015469,0.027357414,-0.09342482,-0.006017118,-0.025992416,-0.018265719,0.08169671,-0.008178296,0.028433014,0.0055204476,0.0048641083,-0.03712568,-0.11200052,-0.049314488,0.0040170033,-0.06331981,0.0072290427,0.0068534603,-0.0037178171,0.32575655,0.08395926,-0.010307969,-0.039482877,-0.02037033,0.085364096,-0.18602572,-0.0025206793,-0.0015801251,-0.04778169,0.051346727,-0.13373461,0.020333476,0.0027960027,0.011692848,-0.032425284,-0.06543713,-0.03911331,-0.06705735,-0.09943406,7.6033187E-4,0.015478297,0.0030875201,-0.016234295,-0.011231421,-0.003999902,-0.0043627364,0.006618547,-0.20851412,0.0044841133,0.001960007,0.010279733,-0.05570969,0.009542639,0.008797392,0.31869772,0.009778704,0.083896264,-0.0031833462,-0.04926956,0.09194644,0.14049953,0.11343999,0.0068182764,-0.1434014,-0.0054175924,-3.8446888E-4,-0.003315376,0.010097834,-0.0036533417,0.0040803854,0.10029941,0.014391219,0.025389371,-0.0035437655,-0.051729023,0.067614615,-0.01583081,-0.17691545,0.014623556,-0.009683874,0.015994517,-0.008506225,0.0046977997,0.0012025355,-0.023884052,-0.18820643,0.07653202,-0.03200735,-0.0053075175,0.008707199,-0.009126822,-0.007356528,-0.06266106,-0.06562633,-0.031104457,-0.0053448784,1.6502956E-4,0.006945444,0.005388296,-0.07420188,-0.003531259,-0.07241037,0.0024118822,-0.010206949,-0.002306631,0.0060584336,0.02316251,0.018091861,-0.099512555,7.348223E-4,5.9629546E-4,0.09591395,0.060623143,-0.0037737733,0.0043147355,0.044896863,0.0030318007,-0.018251896,-0.10206613,-0.011971983,0.008413606,-0.115981065,-0.03836338,1.337841E-4,-0.0032048554,0.09316348,-0.016252546,-0.071028836,0.089589275,0.10665064,-0.14276826,-0.07351477,-0.017121628]]",
      "imageUrl": "https://firebasestorage.googleapis.com/v0/b/facevision-mvvm.appspot.com/o/images%2F-N-DXUgW5zPvmKc9akgN?alt=media&token=aa5ca3f0-798a-4cb0-88ba-d1c38f426aec",
      "key": "-N-DXUgW5zPvmKc9akgN",
      "lastName": "",
      "location": {
        "latitude": 32.0923892,
        "longitude": 34.9723033
      }
    }
  }
}


Models

User

    private String email;
    private String password;
    private String uid;

Wanted

    private String email;
    private String password;
    private String uid;

Location

    private String address;
    private String city;
    private double latitude;
    private double longitude;
    
    public  static final  int LOCATION_SERVICE_ID = 175;
    public  static final String ACTION_START_SERVICE_LOCATION = "startLocationService";
    public  static final String ACTION_STOP_SERVICE_LOCATION = "stopLocationService";

SimilarityClassifier.Recognition

מזהה ייחודי לפנים שזוהו. ספציפית למחלקה, לא למופע של האובייקט.

נמצא בתוך ממשק.

    private final String id;
    private final String title;
    private final Float distance;
    private Object extra;

ViewModels

UserViewModel

extends ViewModel

    private MutableLiveData<ArrayList<User>> userList;


    public UserViewModel() {
       init();
    }

    public void init() {

        if (userList != null) {
            return;

        }

        userList = Repo.getInstance().getUsers();

    }

    
    public LiveData<ArrayList<User>> getUserList() {
        return userList;
    }

    public void setUserList(ArrayList<User> userList) {
        this.userList.setValue(userList);
    }


    public  void clear()
    {
        userList.getValue().clear();
    }

WantedViewModel

extends ViewModel

    private MutableLiveData<ArrayList<Wanted>> wantedList;



    public  WantedViewModel(){
        init();
    }
    
    public LiveData<ArrayList<Wanted>> getWantedList()
    {
        return wantedList;
    }

    public void setWantedList(ArrayList<Wanted> wantedList)
    {
        this.wantedList.setValue(wantedList);
    }

    //private  Repo repo;

    public void init() {

        if (wantedList != null) {
           return;

        }

        wantedList = Repo.getInstance().getWanteds();

    }
    
    public  void clear()
    {
       wantedList.getValue().clear();
    }

Service

PushNotificationService

extends FirebaseMessagingService

(FirebaseMessagingService > EnhancedIntentService > Service)

@Override
public void onMessageReceived(@NonNull RemoteMessage remoteMessage) {

        String title = remoteMessage.getNotification().getTitle();
        String body = remoteMessage.getNotification().getBody();
final String CHANNEL_ID = "NOTI_ID";
        NotificationChannel channel = null;
        if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
        channel = new NotificationChannel(CHANNEL_ID,
        "MyNotification",
        NotificationManager.IMPORTANCE_HIGH);
        }

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
        getSystemService(NotificationManager.class).createNotificationChannel(channel);
        }
        }
        
        if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
        Notification.Builder builder = new Notification.Builder(this, CHANNEL_ID)
        .setContentTitle(title)
        .setContentText(body)
        .setSmallIcon(R.drawable.ic_facial_recognition)
        .setAutoCancel(true);

        NotificationManagerCompat.from(this).notify(1, builder.build());

        }
        super.onMessageReceived(remoteMessage);
        }

Broadcast Receiver

WifiBroadcast

    AlertDialog alertDialog;
    public WifiBroadcast(AlertDialog dialog) {

        this.alertDialog = dialog;

    }
    public boolean isConnected() throws InterruptedException, IOException {
        String command = "ping -c 1 google.com";
        return Runtime.getRuntime().exec(command).waitFor() == 0;
    }
    
    @Override
    public void onReceive(Context context, Intent intent) {
        String action = intent.getAction();
        if (action.equals("android.net.wifi.STATE_CHANGE")) {
            try {
                if(isConnected() == false){
                    Toast.makeText(context, "Wifi is not connected", Toast.LENGTH_SHORT).show();
                    alertDialog.setMessage("Wifi is not connected");
                }
                else {
                    Toast.makeText(context, "Wifi is connected", Toast.LENGTH_SHORT).show();
                    alertDialog.setMessage("Wifi is connected");
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }


            alertDialog.show();
        }
    }

#מימוש באקטיביטי

  WifiBroadcast wifi;
  
    public void createDialog(){
        android.app.AlertDialog.Builder builder = new AlertDialog.Builder(this);// מופע של בילדר
        builder.setTitle("wifi");
        builder.setCancelable(true);
        builder.setPositiveButton("press ok to continue", null);
        dialog = builder.create();// נפעיל את הבילדר ונחזיר רפרנס ל דיאלוג
    }



    @Override
    protected void onResume() {
        super.onResume();
        IntentFilter intentFilter = new IntentFilter("android.net.wifi.STATE_CHANGE");
        registerReceiver(wifi, intentFilter);
        }

    @Override
    protected void onPause() {
        super.onPause();
        unregisterReceiver(wifi);
        }

  • CompileSdk Version: compileSdk 31
  • MinSdk Version: minSdk 21
  • הגדרה לצורך קליטת מודל הזיהוי: aaptOptions { noCompress "tflite"}
* מכשירים ואימולטרים שעליהם נבדק האפליקציה
Pixel 4 XL OnePlus Nord 2 Pixel 4

facevision-wanted-detector-app's People

Contributors

yonigofman avatar

Stargazers

 avatar

Watchers

 avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.