-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit 28940c2
Showing
14 changed files
with
33,698 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
.idea | ||
*.log | ||
*.json | ||
*pyc* | ||
.env |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
FROM jjanzic/docker-python3-opencv:latest | ||
# RPI: FROM sgtwilko/rpi-raspbian-opencv:latest | ||
|
||
WORKDIR /src | ||
|
||
COPY requirements.txt /src/requirements.txt | ||
|
||
RUN pip install --upgrade pip && \ | ||
pip install -r requirements.txt | ||
|
||
COPY src/ /src | ||
|
||
CMD ["/bin/bash"] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
FROM sgtwilko/rpi-raspbian-opencv:latest | ||
#FROM mohaseeb/raspberrypi3-python-opencv:latest | ||
|
||
WORKDIR /src | ||
|
||
COPY requirements.txt /src/requirements.txt | ||
|
||
RUN pip install --upgrade pip && \ | ||
pip install -r requirements.txt | ||
|
||
COPY src/ /src | ||
|
||
CMD ["/bin/bash"] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
Copyright (c) 2019 Guillain Sanchez <[email protected]> | ||
|
||
Private License | ||
|
||
Distribution not allowed |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
# gPhoto-object-extraction | ||
_How to run easily the object recognition_ | ||
|
||
For the demo and to make it more funny: | ||
- the source of information (means the photo galery) is *Google Photo*! | ||
- the object recognized are stored on *AWS S3*! | ||
- all run in docker :) | ||
- ... compatible with Raspberry | ||
|
||
## Pre-requisite | ||
- Docker host | ||
- Internet access | ||
|
||
## Easy Run | ||
After have cloned the repository localy (`git clone https://github.com/guillain/gPhoto-object-extraction`) | ||
and enter in the new directory (`cd gPhoto-object-extraction`) execute the following commands: | ||
|
||
1/ create your own confguration file: | ||
- `cp sample.env .env && vi .env` and add your AWS credentials info | ||
- import the files `google-photo.json` and `google-photo-token.json` as GCP credentials info | ||
- if you need to run it on Raspberry, invert the comment on the first two lines in the `Dockerfile` | ||
|
||
2/ execute the container with the desired date for your Google Photos: `./run "29/12/2019"` | ||
|
||
|
||
## Support | ||
- Original post: | ||
- https://www.hackster.io/mjrobot/real-time-face-recognition-an-end-to-end-project-a10826 | ||
- https://github.com/Mjrovai/OpenCV-Face-Recognition | ||
- Raspberry: https://www.raspberrypi.org | ||
- Docker: https://www.docker.com | ||
- OpenCV: https://opencv.org |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
tensorflow | ||
python-forecastio | ||
opencv-python==4.1.0.25 | ||
awscli | ||
boto3 | ||
numpy | ||
google-api-python-client | ||
httplib2 | ||
oauth2client | ||
python-dotenv |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
#!/bin/bash | ||
. .env | ||
|
||
# my_date=${1} if not provided, go in bash | ||
|
||
# Name of the container (to build & run) | ||
NAME="gphoto-object-extraction" | ||
|
||
# If no date, go in console | ||
if [ "${1}" == "" ]; then | ||
echo -e '\n/!\ No date provided, we jump in the console (exit to go out) /!\ \n' | ||
RUN="/bin/bash" | ||
else | ||
RUN="python app.py" | ||
fi | ||
|
||
# Build the image | ||
docker build -t ${NAME} . | ||
|
||
# Test the image and the cv2 import | ||
docker run -it --rm ${NAME} python -c "import cv2; print(cv2.__version__)" | ||
|
||
# Run the app | ||
docker run -it --rm \ | ||
-e my_date=${1} \ | ||
--env-file=`pwd`/.env \ | ||
-v `pwd`/google-photo.json:/src/google-photo.json \ | ||
-v `pwd`/google-photo-token.json:/src/google-photo-token.json \ | ||
${NAME} ${RUN} | ||
|
||
# Done & Bye | ||
exit 0 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
aws_s3_bucket=my_obects | ||
aws_region_name=eu-central-1 | ||
aws_key_id= | ||
aws_access_key= | ||
|
||
gcp_ident_file=google-photo.json | ||
gcp_token_file=google-photo-token.json |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
from setuptools import setup, find_packages | ||
|
||
NAME="gPhoto-object-extraction" | ||
__version__ = '1.0.0' | ||
AUTHOR="Guillain" | ||
AUTHOR_EMAIL="[email protected]" | ||
|
||
with open('requirements.txt') as f: | ||
requirements = f.read().splitlines() | ||
|
||
setup( | ||
name=NAME, | ||
version=__version__, | ||
description="Image analysis with IA", | ||
url='https://gitlab.com/bo-art-of-bonsai/' + NAME, | ||
author=AUTHOR, | ||
author_email=AUTHOR_EMAIL, | ||
license='Private', | ||
install_requires=requirements, | ||
packages=find_packages(), | ||
zip_safe=False | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,69 @@ | ||
#!/usr/bin/env python | ||
# -*- encoding: utf-8 | ||
import os | ||
import requests | ||
|
||
from lib.aws import AWS | ||
from lib.opencv import OpenCV | ||
from lib.gcp import GCP | ||
|
||
from dotenv import load_dotenv | ||
load_dotenv() | ||
|
||
|
||
def main(my_date): | ||
# my_date = "29/11/2019" | ||
|
||
# Instancies | ||
aws = AWS(bucket=os.getenv('aws_s3_bucket')) | ||
gcp = GCP(cred_file=os.getenv('gcp_token_file')) | ||
cv = OpenCV() | ||
|
||
# Get list of photos | ||
photos = gcp.listMedia(date_filter=my_date, media_type=["PHOTO"]) | ||
if photos is None: | ||
print('error', 'No photos found, exit') | ||
exit(0) | ||
print('{} photos found'.format(len(photos))) | ||
|
||
# For each photo: download, extract each face and store individual face in S3 | ||
face_catalog = [] | ||
for photo in photos: | ||
# Download photo data | ||
photo_data = requests.get(photo['baseUrl']).content | ||
with open(photo['filename'], 'wb') as handler: | ||
handler.write(photo_data) | ||
|
||
faces = cv.extract_faces(photo['filename']) | ||
#faces = cv.extract_faces_from_buffer(photo_data) | ||
|
||
i_face = 1 | ||
for face in faces: | ||
filename = 'extract/{}'.format(face) | ||
|
||
aws.s3_upload_file(face, filename) | ||
os.remove(face) | ||
#aws.s3_upload_data(face, filename) | ||
|
||
face = dict(photo) | ||
face['face_id'] = i_face | ||
face['face_filename'] = filename | ||
#del face['baseUrl'] | ||
face_catalog.append(face) | ||
|
||
i_face = i_face + 1 | ||
|
||
os.remove(photo['filename']) | ||
print('{} face(s) found in the photo {}'.format(i_face - 1, photo['filename'])) | ||
|
||
if face_catalog: | ||
for face in face_catalog: | ||
print('JSON catalog of faces\n{}'.format(face)) | ||
print('{} face(s) found in total'.format(len(face_catalog))) | ||
else: | ||
print('No face found :(') | ||
|
||
|
||
if __name__ == '__main__': | ||
main(os.getenv('my_date')) | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
import os | ||
import boto3 | ||
from io import BytesIO | ||
|
||
|
||
class AWS(object): | ||
def __init__(self, | ||
type='s3', | ||
region=os.getenv('aws_region_name'), | ||
key_id=os.getenv('aws_key_id'), | ||
access_key=os.getenv('aws_access_key'), | ||
bucket='bo-infra-backup'): | ||
self.region_name = region | ||
self.bucket_name = bucket | ||
|
||
self.session = boto3.Session( | ||
aws_access_key_id=key_id, | ||
aws_secret_access_key=access_key) | ||
|
||
def init(self, type='s3', obj='resource'): | ||
if obj == 'resource': | ||
return self.session.resource(type, region_name=self.region_name) | ||
elif obj == 'client': | ||
return self.session.client(type, region_name=self.region_name) | ||
|
||
def s3_download(self, file, output): | ||
s3 = self.init(type='s3', obj='resource') | ||
file_stream = BytesIO() | ||
|
||
s3.Object(self.bucket_name, file).download_file(output) | ||
s3.Object(self.bucket_name, file).download_fileobj(file_stream) | ||
|
||
def s3_upload_file(self, file_in, file_out): | ||
s3 = self.init(type='s3', obj='resource') | ||
|
||
s3.Bucket(self.bucket_name).upload_file(Filename=file_in, Key=file_out) | ||
|
||
def s3_upload_data(self, data, filename): | ||
s3 = self.init(type='s3', obj='resource') | ||
|
||
s3.Object(self.bucket_name, filename).put(Body=data) | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,74 @@ | ||
import os | ||
from googleapiclient.discovery import build, MediaFileUpload | ||
from httplib2 import Http | ||
from oauth2client import file, client, tools | ||
|
||
|
||
class GCP(object): | ||
def __init__(self, cred_file, store_file=os.getenv('gcp_ident_file')): | ||
self.store_file = store_file | ||
# self.photo_scopes = 'https://www.googleapis.com/auth/photoslibrary.readonly' | ||
self.photo_scopes = 'https://www.googleapis.com/auth/photoslibrary.sharing' | ||
|
||
store = file.Storage(self.store_file) | ||
creds = store.get() | ||
if not creds or creds.invalid: | ||
flow = client.flow_from_clientsecrets(cred_file, self.photo_scopes) | ||
creds = tools.run_flow(flow, store) | ||
|
||
self.lib = build('photoslibrary', 'v1', http=creds.authorize(Http())) | ||
|
||
def format_date(self, my_date): | ||
# my_date = "27/12/2019" | ||
|
||
my_date_arr = my_date.split('/') | ||
return [{"day": my_date_arr[0], "month": my_date_arr[1], "year": my_date_arr[2]}] | ||
|
||
def listMedia(self, date_filter=None, media_type=["PHOTO", "VIDEO"]): | ||
# date_filter = "27/12/2019" or "0/12/2019" for all days of december | ||
|
||
nextpagetoken = 'Dummy' | ||
filters = { "mediaTypeFilter": {"mediaTypes": media_type} } | ||
if date_filter is not None: | ||
filters = { | ||
"dateFilter": {"dates": self.format_date(date_filter)}, | ||
"mediaTypeFilter": {"mediaTypes": media_type} | ||
} | ||
|
||
res = [] | ||
while nextpagetoken != '': | ||
nextpagetoken = '' if nextpagetoken == 'Dummy' else nextpagetoken | ||
results = self.lib.mediaItems().search( | ||
body={ | ||
"filters": filters, | ||
"pageSize": 100, | ||
"pageToken": nextpagetoken, | ||
} | ||
).execute() | ||
|
||
# The default number of media items to return at a time is 25. The maximum pageSize is 100. | ||
items = results.get('mediaItems', []) | ||
nextpagetoken = results.get('nextPageToken', '') | ||
for item in items: | ||
res.append(item) | ||
|
||
return res | ||
|
||
def uploadMedia(self, media, name='', mimetype='image/png'): | ||
media = MediaFileUpload(media, mimetype=mimetype, resumable=True) | ||
request = self.lib.create(media_body=media, body={'name': name}) | ||
response = None | ||
while response is None: | ||
status, response = request.next_chunk() | ||
|
||
return response | ||
|
||
def listAlbums(self): | ||
r = self.lib.albums().list(pageSize=10).execute() | ||
items = r.get('albums', []) | ||
return items | ||
|
||
def createAlbum(self, title): | ||
r = self.lib.albums().create(body={'album':{'title':title}}).execute() | ||
return r.id | ||
|
Oops, something went wrong.