如何从另一个类和文件调用实例变量

时间:2019-03-18 03:54:19

标签: python python-3.x instance-variables

我有一个问题,我有4个文件 app.py face.py camera.py db。 py face.py 文件中,我有一个变量调用 known_encoding_faces 。如果我将打印代码放在face.py中并运行app.py,结果将显示在命令提示符中。

我的问题是如何在我的camera.py中使用 known_encoding_faces 变量?我的预期结果是,当我运行app.py并打开网络摄像头时,命令提示符将显示打印的 known_encoding_faces 输出。我相信,如果这项工作意味着该 known_encoding_faces 变量可以成功地用于camera.py文件。

在这里附上我的代码。希望有人可以在这件事上帮助我。

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()

1 个答案:

答案 0 :(得分:2)

known_encoding_facesFace对象的成员。这意味着它本身并不存在-作为证据,请注意,您仅引用self.known_encoding_faces而不是known_encoding_faces。您需要初始化一些Face对象,然后才能使用它。此外,您似乎需要在该对象上调用load_all才能正确初始化它。您所需的最小内容是:

from face import Face

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

如果您希望这种方法不考虑对象的创建而存在,则需要重新考虑您的设计,并将其从类中删除。

如果希望从主脚本中调用它,则可以要求此变量来初始化摄像机:

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

camera.py中的

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

,现在您可以在此类中使用self.known_encoding_faces