From 1134fb5eb101dbedd6bd0f7c36c9df26390e7ae8 Mon Sep 17 00:00:00 2001 From: "Jyoti Bisht (Joe)" Date: Tue, 19 Jul 2022 18:22:25 +0530 Subject: [PATCH 1/4] updated facenet.py --- corelib/facenet/facenet.py | 85 +++++++++++++++++++++++++++----------- 1 file changed, 62 insertions(+), 23 deletions(-) diff --git a/corelib/facenet/facenet.py b/corelib/facenet/facenet.py index 6c269c7..2b107fa 100644 --- a/corelib/facenet/facenet.py +++ b/corelib/facenet/facenet.py @@ -1,4 +1,6 @@ """Functions for building the face recognition network. + Reference: + https://github.com/davidsandberg/facenet/blob/master/src/facenet.py """ @@ -8,11 +10,9 @@ import os from subprocess import Popen, PIPE -import cv2 -import numpy import tensorflow as tf import numpy as np -# from scipy import misc +from scipy import misc from sklearn.model_selection import KFold from scipy import interpolate from tensorflow.python.training import training @@ -70,7 +70,13 @@ def center_loss(features, label, alfa, nrof_classes): def get_image_paths_and_labels(dataset): - + """ Gets image paths and labels from the dataset sent as input + Args: + dataset: the data of images + Returns: + image paths and labels + + """ logger.info(msg="get_image_paths_and_labels called") image_paths_flat = [] labels_flat = [] @@ -81,7 +87,15 @@ def get_image_paths_and_labels(dataset): def shuffle_examples(image_paths, labels): + """Takes inputs as image paths and labels and shuffles them to create a dynamic sample + Args: + image_paths: path of images generated previously + labels: labels of images generated previously + Returns: + image paths and labels post shuffling + + """ logger.info(msg="shuffle_examples called") shuffle_list = list(zip(image_paths, labels)) random.shuffle(shuffle_list) @@ -89,18 +103,16 @@ def shuffle_examples(image_paths, labels): return image_paths_shuff, labels_shuff -def rotate_image(image, angle): - image_center = tuple(np.array(image.shape[1::-1]) / 2) - rot_mat = cv2.getRotationMatrix2D(image_center, angle, 1.0) - result = cv2.warpAffine(image, rot_mat, image.shape[1::-1], flags=cv2.INTER_LINEAR) - return result - - def random_rotate_image(image): - + """Rotates the given image using random angle generated in the function + Args: + image: the input image to perform the function on + Returns: + the rotated array of image + """ logger.info(msg="random_rotate_image called") angle = np.random.uniform(low=-10.0, high=10.0) - return rotate_image(image, angle) + return misc.imrotate(image, angle, 'bicubic') # 1: Random rotate @@ -193,7 +205,19 @@ def _add_loss_summaries(total_loss): def train(total_loss, global_step, optimizer, learning_rate, moving_average_decay, update_gradient_vars, log_histograms=True): + """ Extensive function to train the model + Args: + total_loss: total loss incurred + global_step: the number of batches seen by the graph + optimizer: defines the type of optimizer + learning_rate: a hyperparameter controlling how much to change the model in response to the estimated + error each time the model weights are updated. For every optimizer, we keep learning_rate constant. + moving_average_decay: + update_gradient_vars: + log_histogram: set to true to create histograms for gradients + Returns: + """ logger.info(msg="train called") # Generate moving averages of all losses and associated summaries. loss_averages_op = _add_loss_summaries(total_loss) @@ -246,7 +270,7 @@ def train(total_loss, global_step, optimizer, learning_rate, moving_average_deca def prewhiten(x): - + """ormalizes the range of the pixel values of input images to make training easier""" logger.info(msg="prewhiten called") mean = np.mean(x) std = np.std(x) @@ -256,7 +280,14 @@ def prewhiten(x): def crop(image, random_crop, image_size): - + """Crops the input image + Args: + image: input image + random_crop: turned true or false for randomly cropping and vice versa + image_size: size of the image + Returns: + cropped image + """ logger.info(msg="crop called") if image.shape[1] > image_size: sz1 = int(image.shape[1] // 2) @@ -272,7 +303,16 @@ def crop(image, random_crop, image_size): def flip(image, random_flip): + """ flips the entries in each row in the left/right direction. + Columns are preserved, but appear in a different order than before if random_flip is on + + Args: + image: input image + random_flip: parameter deciding the randomness of flip + Returns: + image after being flipped + """ logger.info(msg="flip called") if random_flip and np.random.choice([True, False]): image = np.fliplr(image) @@ -280,7 +320,6 @@ def flip(image, random_flip): def to_rgb(img): - logger.info(msg="to_rgb called") w, h = img.shape ret = np.empty((w, h, 3), dtype=np.uint8) @@ -294,8 +333,8 @@ def load_img(img, do_random_crop, do_random_flip, image_size, do_prewhiten=True) # nrof_samples = len(image_paths) images = np.zeros((1, image_size, image_size, 3)) # for i in range(nrof_samples): - # img = cv2.imread(image_path) - # img = cv2.imresize(img,(160,160,3)) + # img = misc.imread(image_path) + # img = misc.imresize(img,(160,160,3)) if img.ndim == 2: img = to_rgb(img) if do_prewhiten: @@ -312,14 +351,14 @@ def load_data(image_paths, do_random_crop, do_random_flip, image_size, do_prewhi nrof_samples = len(image_paths) images = np.zeros((nrof_samples, image_size, image_size, 3)) for i in range(nrof_samples): - img = cv2.imread(image_paths[i]) + img = misc.imread(image_paths[i]) if img.ndim == 2: img = to_rgb(img) if do_prewhiten: img = prewhiten(img) img = crop(img, do_random_crop, image_size) img = flip(img, do_random_flip) - img = cv2.imresize(img, (160, 160, 3)) + img = misc.imresize(img, (160, 160, 3)) # print(image_paths[i].split('/')[6],img.shape,images.shape) images[i, :, :, :] = img return images @@ -404,8 +443,9 @@ def get_dataset(path, has_class_directories=True): logger.info(msg="get_dataset called") dataset = [] path_exp = os.path.expanduser(path) - classes = sorted([path for path in os.listdir(path_exp) - if os.path.isdir(os.path.join(path_exp, path))]) + classes = [path for path in os.listdir(path_exp) + if os.path.isdir(os.path.join(path_exp, path))] + classes.sort() nrof_classes = len(classes) for i in range(nrof_classes): class_name = classes[i] @@ -620,7 +660,6 @@ def calculate_val(thresholds, embeddings1, embeddings2, actual_issame, far_targe dist[train_set], actual_issame[train_set]) if np.max(far_train) >= far_target: - # f = cv2.resize(img,None, fx = far_train, fy = thresholds, interpolation = cv2.INTER_LINEAR) f = interpolate.interp1d(far_train, thresholds, kind='slinear') threshold = f(far_target) else: From 65acf029f5788ac53cb84b3f61babc08235c849c Mon Sep 17 00:00:00 2001 From: "Jyoti Bisht (Joe)" Date: Tue, 19 Jul 2022 18:45:38 +0530 Subject: [PATCH 2/4] updated contributing.md --- contributing.md | 75 +++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 64 insertions(+), 11 deletions(-) diff --git a/contributing.md b/contributing.md index b623834..faaca80 100644 --- a/contributing.md +++ b/contributing.md @@ -1,3 +1,33 @@ +Table of contents: +- [Contributing to Rekognition](#Contributing-to-Rekognition) +- [Making a PR](#making-a-pr) +- [Asking for help](#asking-for-help) +- [Development environment setup](#Development-environment-setup) + +As beginners, navigating the codebase and finding your way out of the documentation can become difficult. This page will help you understand everything about contributing to howdoi and the best practices in open source as well. + +## Contributing to Rekognition +- Follow the page Setting up the development environment for setting up the development environment for Rekognition. +- Finding your first issue +- Go to issues in the Rekognition repo. +- Find the issues which you might be interested to work on. Or, you can also come up with your own ideas of improving the code. +- After finding the issue you are interested in : If the issue is an existing one, comment on the issue and ask for it to be assigned to you. Or, if the issue is unlisted and new , create a new issue and fill every information needed in the issues template provided by howdoi and ask for it to be assigned to you. +- After receiving confirmation, start working on the issue and whenever and wherever help is needed, comment on the issue itself describing your query in detail. +- A good guide on how to collaborate efficiently can be found here. + +## Making a PR +- After you have worked on the issue and fixed it, we need to merge it from your forked repository into the Rekognition repository by making a PR. +- Each PR made should pass all the tests. We have new Github Actions in place for CI/CD. +- Once your commit passes all the tests, make a PR and wait for it to be reviewed and merged. + + +## Asking for help +- At times, help is needed while solving the issue. We recommend the following step for asking for help when you get stuck: +- Read from our documentation to see if your question has already been answered. +- Comment on the issue you are working on describing in detail what problems you are facing. +- Make sure to write your query in detail and if it is a bug, include steps to reproduce it. +- If you are not working on any issue and have a question to be answered, open a new issue on Github and wait for a reply. + # Development Environment setup ## Install python 3.6 ``` @@ -6,14 +36,29 @@ sudo apt-get update sudo apt-get install python3.6 ``` +## For MacOS: +``` +brew install python +``` + ## Clone the repository and setup venv ``` -git clone https://github.com/pymit/Rekognition +git clone https://github.com/CCExtractor/Rekognition cd Rekognition -./setup.sh +../setup.sh source myenv/bin/activate ``` + +### For MacOS: +git clone https://github.com/CCExtractor/Rekognition +./setup.sh +cd Rekognition +python3 -m virtualenv myenv +source $PWD/myenv/bin/activate +pip install -r ../requirements.txt + +NOTE: Sometimes an error "permission denied" may be shown when you try to run `setup.sh`. For this, try: `chmod 755 setup.sh` in root directory to change permissions. *** ## Postgres setup @@ -30,16 +75,20 @@ source myenv/bin/activate ALTER USER admin CREATEDB; ALTER DATABASE pmr OWNER TO admin; *** +## Postgres setup for MacOS -## ReactJS setup for frontend - - git clone https://github.com/pymit/RekoUI - cd RekoUI - sudo apt install npm - sudo npm install -g npm@latest - npm install - npm start -*** + brew update + brew install postgresql + brew services start postgresql + psql postgres + CREATE DATABASE pmr; + CREATE USER admin WITH PASSWORD 'admin'; + ALTER ROLE admin SET client_encoding TO 'utf8'; + ALTER ROLE admin SET default_transaction_isolation TO 'read committed'; + ALTER ROLE admin SET timezone TO 'UTC'; + ALTER USER admin CREATEDB; + ALTER DATABASE pmr OWNER TO admin; +*** ## Downloading the models ##### current directory Rekognition @@ -107,3 +156,7 @@ python manage.py runserver 8000 Django app can be accessed at http://localhost:8000 ReactJS app can be accessed at http://localhost:3000 + + + + From 498dc5fcbc961e8a8f5f08c1403c43c5515998f1 Mon Sep 17 00:00:00 2001 From: "Jyoti Bisht (Joe)" Date: Tue, 19 Jul 2022 18:51:15 +0530 Subject: [PATCH 3/4] added banner in README.md --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 3a8d34c..cf90096 100644 --- a/README.md +++ b/README.md @@ -8,6 +8,7 @@ Google Summer Of Code Project under CCExtractor Development [![GPLv3 license](https://img.shields.io/badge/License-GPLv3-blue.svg)](https://github.com/ccextractor/Rekognition/blob/master/LICENSE) --- +![bannerimage](https://github.com/CCExtractor/Rekognition/banner.png) This project aims at providing a free alternative to Amazon Rekognition services. From d67c4f6ae317ad5a44ab99ef0aaa8c06cd63eac7 Mon Sep 17 00:00:00 2001 From: "Jyoti Bisht (Joe)" Date: Tue, 19 Jul 2022 19:15:21 +0530 Subject: [PATCH 4/4] updated retina_net.py --- corelib/RetinaFace/retina_net.py | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/corelib/RetinaFace/retina_net.py b/corelib/RetinaFace/retina_net.py index e591141..ed90d7c 100644 --- a/corelib/RetinaFace/retina_net.py +++ b/corelib/RetinaFace/retina_net.py @@ -13,7 +13,16 @@ def retry_request(retries=3, backoff_factor=0.3, status_forcelist=(500, 502, 504), session=None): + """ to retry requests made again + Args: + retries: number of retries + backoff_factor: to configure the length of delay after each failed login attempt + status_forcelist: HTTP/HTTPS status codes for retrying + Returns: + current session of the request + + """ logger.info(msg="retry_request called") session = session or requests.Session() retry = Retry(