0

I have a question, I have 4 file app.py, face.py, camera.py and db.py Inside face.py file I have one variable call known_encoding_faces. If I put print code inside my face.py and run the app.py the result will display in my command prompt.

My question is how can i use known_encoding_faces variable in my camera.py? My expected result is when i run my app.py and open my webcam the command prompt will show the printed known_encoding_faces output. I believe if this work means this known_encoding_faces variable successfully can be used by camera.py file.

Here I attach my code. Hope someone can help me regarding on this matter.

app.py

from flask import Flask, Response, json, render_template
from werkzeug.utils import secure_filename
from flask import request
from os import path, getcwd
import time
from face import Face
from db import Database
app = Flask(__name__)
import cv2
from camera import VideoCamera


app.config['file_allowed'] = ['image/png', 'image/jpeg']
app.config['train_img'] = path.join(getcwd(), 'train_img')
app.db = Database()
app.face = Face(app)


def gen(camera):
    while True:
        frame = camera.get_frame()
        yield (b'--frame\r\n'
               b'Content-Type: image/jpeg\r\n\r\n' + frame + b'\r\n\r\n')

@app.route('/video_feed')
def video_feed():
    return Response(gen(VideoCamera()),
                    mimetype='multipart/x-mixed-replace; boundary=frame')

@app.route('/')
def index():
    return render_template('index.html')

def success_handle(output, status=200, mimetype='application/json'):
    return Response(output, status=status, mimetype=mimetype)

face.py

import face_recognition
from os import path
import cv2
import face_recognition



class Face:
    def __init__(self, app):
        self.train_img = app.config["train_img"]
        self.db = app.db
        self.faces = []
        self.face_user_keys = {}
        self.known_encoding_faces = []  # faces data for recognition
        self.load_all()

    def load_user_by_index_key(self, index_key=0):

        key_str = str(index_key)

        if key_str in self.face_user_keys:
            return self.face_user_keys[key_str]

        return None

    def load_train_file_by_name(self,name):
        trained_train_img = path.join(self.train_img, 'trained')
        return path.join(trained_train_img, name)

    def load_unknown_file_by_name(self,name):
        unknown_img = path.join(self.train_img, 'unknown')
        return path.join(unknown_img, name)


    def load_all(self):
        results = self.db.select('SELECT faces.id, faces.user_id, faces.filename, faces.created FROM faces')
        for row in results:

            user_id = row[1]
            filename = row[2]

            face = {
                "id": row[0],
                "user_id": user_id,
                "filename": filename,
                "created": row[3]
            }

            self.faces.append(face)

            face_image = face_recognition.load_image_file(self.load_train_file_by_name(filename))
            face_image_encoding = face_recognition.face_encodings(face_image)[0]
            index_key = len(self.known_encoding_faces)
            self.known_encoding_faces.append(face_image_encoding)
            index_key_string = str(index_key)
            self.face_user_keys['{0}'.format(index_key_string)] = user_id

    def recognize(self,unknown_filename):
        unknown_image = face_recognition.load_image_file(self.load_unknown_file_by_name(unknown_filename))
        unknown_encoding_image =  face_recognition.face_encodings(unknown_image)[0]

        results = face_recognition.compare_faces(self.known_encoding_faces, unknown_encoding_image);

        print("results", results)

        index_key = 0
        for matched in results:

            if matched:
                # so we found this user with index key and find him
                user_id = self.load_user_by_index_key(index_key)

                return user_id

            index_key = index_key + 1
        return None

camera.py

import face_recognition
from os import path
import cv2
from db import Database
from face import Face

class VideoCamera(object):
    def __init__(self):
        # Using OpenCV to capture from device 0. If you have trouble capturing
        # from a webcam, comment the line below out and use a video file
        # instead.
        self.video = cv2.VideoCapture(0)
        # If you decide to use video.mp4, you must have this file in the folder
        # as the main.py.
        # self.video = cv2.VideoCapture('video.mp4')

    def __del__(self):
        self.video.release()

    def get_frame(self):
        success, image = self.video.read()
        # We are using Motion JPEG, but OpenCV defaults to capture raw images,
        # so we must encode it into JPEG in order to correctly display the
        # video stream.
        ret, jpeg = cv2.imencode('.jpg', image)
        return jpeg.tobytes()
9
  • You can import variables, doesn't that work? Commented Mar 18, 2019 at 4:45
  • @Nishant Doesn't work :( I have try for for few day but fail..maybe you can show me an how the way to do. I can try edit my code Commented Mar 18, 2019 at 4:47
  • just look into your variable name properly. declared known_encoding_faces list in the face.py file I can't see the known_face_encoding variable in it. Commented Mar 18, 2019 at 5:22
  • @VaradarajuG I already declare in my face.py file self.known_encoding_faces = []. I believe it instance variable Commented Mar 18, 2019 at 5:34
  • 1
    @VaradarajuG Thank for your effort sir.. Thanks for advice too :) Commented Mar 18, 2019 at 6:46

1 Answer 1

2

known_encoding_faces is a member of a Face object. That means it does not exist on its own - as evidence, note you only reference self.known_encoding_faces rather than just known_encoding_faces. You need to initialize some Face object, and than you can use it. Further more, it looks like you would need to call load_all on said object to properly initialize it. The minimal thing you need is some thing like:

from face import Face

aface = Face(app) #You would need an app here
aface.load_all()
known_encoding_faces = aface.known_encoding_faces

If you are expecting this to exist irrespective of an objects creation, you need to rethink your design, and take it out of your class.

If you are expecting this to be called from the main script, you can demand this variable to initialize your camera:

VideoCamera(app.face.known_encoding_faces) #Called from main script

and in camera.py:

class VideoCamera(object):
    def __init__(self,known_face_encodings):
        self.known_encoding_faces = known_face_encodings
        self.video = cv2.VideoCapture(0)

and in this class you can now use self.known_encoding_faces.

Sign up to request clarification or add additional context in comments.

8 Comments

Thanks for advise. Currently I already put this code but doesn't work.. I believe it almost. As you mention may I know how can i get the app so that my aface.face(app) can be executed? Where i should place it in my app.py?
@iszzulikhwan91 look at the second example. Change VideoCamera to take this list in its init method, and then when you create a VideoCamera in your app.py, just send it app.face.known_encoding_faces which is already initialized.
Thank you very much @kabanus. The code works well. Thanks you so much sir for our effort. I really appreciate it. Sir I interested to know about the first solution you provided. If i want to used it. Do i need to put in app.py?
@iszzulikhwan91 You would need it in camera.py since that is where you want to use it. But then you would need to initialize and app and a Face. I am not sure that makes sense in your context, since they already exist in app.py by the time you initialize the VideoCamera. You would have to create the app and Face in camera, which I do not think makes sense. That is why I would use the second solution -
you mention that I have to initialized and app and face. I try this method before but it show error. That why I am interested to know. In my case how to initialize the app. Do I need to declare this app = Flask(name) again?
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.