コード例 #1
0
class Voice(Elk):
    said = ElkAttribute(mode='rw', type=str)
    muted = ElkAttribute(mode='rw', type=bool, default=False)
    temp_path = ElkAttribute(mode='rw',
                             type=str,
                             builder='_temp_path',
                             lazy=True)
    play_filename = ElkAttribute(mode='rw', type=str, default='pcvoice.mp3')

    def _temp_path(self):
        path = os.path.join(gettempdir(), '.{}'.format(hash(os.times())))
        os.makedirs(path)
        return path

    def mute(self):
        self.muted = True

    def unmute(self):
        self.muted = False

    def play_file(self, music_file, volume=0.8):
        # set up the mixer
        #         freq = 44100     # audio CD quality
        #         bitsize = -16    # unsigned 16 bit
        #         channels = 1     # 1 is mono, 2 is stereo
        #         buffer = 2048    # number of samples (experiment to get best sound)
        #         buffer = 4096  # number of samples (experiment to get best sound)
        #         pg.mixer.init(freq, bitsize, channels, buffer)

        mp3 = mutagen.mp3.MP3(music_file)
        pg.mixer.init(frequency=mp3.info.sample_rate)

        # volume value 0.0 to 1.0
        pg.mixer.music.set_volume(volume)
        clock = pg.time.Clock()
        try:
            pg.mixer.music.load(music_file)
        except pg.error:
            log.error("File {} not found! ({})".format(music_file,
                                                       pg.get_error()))
            return
        pg.mixer.music.play()
        while pg.mixer.music.get_busy():
            clock.tick(30)
        pg.mixer.music.stop()
        pg.mixer.quit()

    def say(self, text):
        self.said = text
        if not self.muted:
            tts = gTTS(text=text, lang='en')
            tts.save(self.play_filename)
            self.play_file(self.play_filename)
コード例 #2
0
class RPICamera(Camera):
    stream = ElkAttribute(mode='rw', builder='_stream', lazy=True)

    def _camera(self):
        try:
            #from picamera.array import PiRGBArray
            #from picamera import PiCamera
            pass
        except ImportError:
            print("PI camera is not detected")
            return None

        camera = PiCamera()
        camera.resolution = (640, 480)
        #camera.framerate = 32
        return camera

    def _stream(self):
        stream = PiRGBArray(self.camera, size=(640, 480))
        # allow the camera to warmup
        time.sleep(1)
        return stream

    def capture(self):
        self.stream.truncate(0)
        self.camera.capture(self.stream, format="bgr", use_video_port=True)
        # grab the raw NumPy array representing the image,
        # then initialize the timestamp
        # and occupied/unoccupied text
        image = self.stream.array
        return image
コード例 #3
0
ファイル: TestCamera.py プロジェクト: slavalitvinov/Homager
class TestCamera(Camera):
    image = ElkAttribute(mode='rw')

    def _camera(self):
        return None

    def capture(self):
        return self.image
コード例 #4
0
ファイル: Camera.py プロジェクト: kegan1998/Homager
class Camera(Elk):
    camera = ElkAttribute(mode='ro', builder='_camera', lazy=True)

    def __del__(self):
        if self.camera is not None:
            self.camera.release()

    def _camera(self):
        return cv2.VideoCapture(0)

    def capture(self):
        ret, frame = self.camera.read()
        return frame
コード例 #5
0
ファイル: Master.py プロジェクト: kegan1998/Homager
class Master(Elk):
    face_agent = ElkAttribute(mode='rw', type=FaceAgent,
        builder="_face_agent", lazy=True)
    voice = ElkAttribute(mode='rw', type=(Voice, NoneType),
        builder="_voice", lazy=True)
    saw = ElkAttribute(mode='rw', type=str,
        default='')
    face_recognition_threshold = ElkAttribute(mode='rw', type=int,
        default=150)
    camera = ElkAttribute(mode='rw', type=Camera,
        builder="_camera", lazy=True)
    memory = attr(mode='rw', type=Memory,
        builder="_memory", lazy=True)
    enable_video = ElkAttribute(mode='rw', type=bool,
        default=False)
    sleep_delay = ElkAttribute(mode='rw', type=float,
        default=1.0)
    interrupt = attr(mode='rw', type=bool,
        default=False)

    def _face_agent(self):
        agent = FaceAgent()
        agent.init()
        return agent

    def _voice(self):
        return Voice()

    def _camera(self):
        return RPICamera()

    def _memory(self):
        return Memory()

    def best_recognized_face(self, faces):
        best = None
        index = 0
        for face in faces:
            print_confidence = face['confidence']
            if print_confidence > 1000:
                print_confidence = 'uncertain'
            else:
                print_confidence = str(print_confidence)
            if self.enable_video:
                index += 1
                cv2.imshow('Face' + str(index), face['image'])

            log.info('found face %s with %s confidence' %
                (face['predicted'], print_confidence))
            if best is None or best['confidence'] < face['confidence']:
                best = face
        return best

    def biggest_face(self, faces):
        biggest = None
        biggest_size = 0
        for face in faces:
            size = face['size']
            size = (size[0] + size[1]) / 2
            if size > biggest_size:
                biggest = face
                biggest_size = size
        return biggest

    def recognize(self, image):
        assert image is not None, 'image instance is mandatory'
        self.faces = self.face_agent.recognize(image)
        if self.enable_video:
            self.face_agent.show_faces(image, self.faces, 5000)
            pass
        saw = ''
        self.face = None
        self.biggest_face = None
        if not self.faces:
            #log.info("could not find any face")
            pass
        else:
            self.face = self.best_recognized_face(self.faces)
            if not self.face:
                #log.info("could not recognize any face")
                saw = 'FACE'
            else:
                if self.face['confidence'] < self.face_recognition_threshold:
                    saw = self.face['predicted']
                else:
                    saw = 'FACE'
            if saw == 'FACE':
                self.biggest_face = self.biggest_face(faces)
                if self.biggest_face:
                    log.info("found a new face")
                    self.face_agent.new_face(self.biggest_face['image'])
        self.saw = saw

    def look(self):
        image = self.camera.capture()
        self.recognize(image)
        if self.saw == 'FACE':
            self.voice.say('hi, I do not know you')
        elif self.saw != '':
            if self.voice:
                self.voice.say('hi ' + self.saw)
            if self.memory:
                if self.memory.remember({
                        'place': 'kitchen',
                        'noun': self.saw,
                        'verb': 'see'
                    }):
                    self.face_agent.remember_face(self.face)
                    self.face_agent.remember_image(image, self.saw)

    def stop(self):
        self.interrupt = True

    def run(self):
        while not self.interrupt:
            self.look()
            if self.enable_video:
                if cv2.waitKey(200) & 0xFF == ord('q'):
                    break
            else:
                if self.saw == '':
                    if self.sleep_delay > 3.0:
                        self.sleep_delay -= 0.1
                    else:
                        self.sleep_delay = 3.0
                else:
                    self.sleep_delay = 5.0
                time.sleep(self.sleep_delay)
        cv2.destroyAllWindows()
コード例 #6
0
ファイル: FaceImage.py プロジェクト: slavalitvinov/Homager
class FaceImage(Elk):
    image = ElkAttribute(mode='rw',
                         type=(types.NoneType, np.ndarray),
                         builder='_image',
                         lazy=True)
    filename = ElkAttribute(mode='ro', type=str)

    def _image(self):
        if self.filename:
            image = self._load_from_file(self.filename)
            return image
        return Image()

    def _load_from_file(self, filename):
        log.info("reading: " + filename)
        image = Image.open(filename)
        image = image.convert('L')
        image = np.array(image, 'uint8')
        return image

    def gray(self):
        image = cv2.cvtColor(self.image, cv2.COLOR_BGR2GRAY)
        return image

    def resize(self, size):
        h, w = self.image.shape[:2]
        log.info("resizing to (%d,%d)" % (h, w))
        sh, sw = size
        if h > sh or w > sw:  # shrinking
            interp = cv2.INTER_AREA
        else:
            interp = cv2.INTER_CUBIC
        aspect = w / h
        if aspect > 1:  # horizontal image
            new_w = sw
            new_h = np.round(new_w / aspect).astype(int)
            pad_vert = (sh - new_h) / 2
            pad_top, pad_bot = np.floor(pad_vert).astype(int), \
                np.ceil(pad_vert).astype(int)
            pad_left, pad_right = 0, 0
        elif aspect < 1:  # vertical image
            new_h = sh
            new_w = np.round(new_h * aspect).astype(int)
            pad_horz = (sw - new_w) / 2
            pad_left, pad_right = np.floor(pad_horz).astype(int), \
                np.ceil(pad_horz).astype(int)
            pad_top, pad_bot = 0, 0
        else:
            new_h, new_w = sh, sw
            pad_left, pad_right, pad_top, pad_bot = 0, 0, 0, 0
        image = cv2.resize(self.image, (new_w, new_h), interpolation=interp)
        image = cv2.copyMakeBorder(image,
                                   pad_top,
                                   pad_bot,
                                   pad_left,
                                   pad_right,
                                   borderType=cv2.BORDER_CONSTANT,
                                   value=0)
        self.image = image
        return image

    def align_eyes(self, left, right, image=None):
        if image is None:
            image = self.image

        (ex, ey, ew, eh) = left
        eye_left = (ex, ey)
        (ex, ey, ew, eh) = right
        eye_right = (ex, ey)
        scale = (0.15, 0.10)
        size = (image.shape[0], image.shape[1])
        dest_sz = (image.shape[0], image.shape[1])
        #eye_left=(0,0), eye_right=(0,0), offset_pct=(0.25,0.25), dest_sz = (250,250)):

        # rotate
        eye_direction = (eye_right[0] - eye_left[0],
                         eye_right[1] - eye_left[1])
        rotation = math.atan2(float(eye_direction[1]), float(eye_direction[0]))
        rotation = rotation * 180 / math.pi
        dist = math.hypot(eye_left[0] - eye_right[0],
                          eye_left[1] - eye_right[1])

        sz = image.shape
        if len(sz) > 2:
            sz = sz[:2]

        mat = cv2.getRotationMatrix2D(eye_left, rotation, 1.0)
        result = cv2.warpAffine(image, mat, sz, flags=cv2.INTER_CUBIC)

        # cut
        #         dest_h = math.floor(float(dest_scale[0])*dest_sz[0])
        #         dest_v = math.floor(float(dest_scale[1])*dest_sz[1])
        # #        reference = dest_sz[0] - 2.0*offset_h
        #         reference = dest_sz[0] - 2.0*offset_h
        #         scale = float(dist) / float(reference)
        #         print( dist, reference )
        #         print( scale )

        crop_xy = (size[0] * scale[0], size[1] * scale[1])
        #crop_size = (dest_sz[0]*scale, dest_sz[1]*scale)
        crop_size = (size[0] * (1 - 2 * scale[0]),
                     size[1] * (1 - 2 * scale[1]))
        result = result[int(crop_xy[1]):int(crop_xy[1] + crop_size[1]),
                        int(crop_xy[0]):int(crop_xy[0] + crop_size[0])]

        self.image = result
        return result

    def normalize(self):
        #image = self.resize((100, 100))
        image = self.image
        image = cv2.equalizeHist(image)
        #clahe = cv2.createCLAHE(clipLimit=2.0, tileGridSize=(8, 8))
        #image = clahe.apply(image)
        #image = cv2.bilateralFilter(image, 5, 75, 75)
        self.image = image
        return image
コード例 #7
0
class Memory(Elk):
    filename = ElkAttribute(mode='rw',
                            type=str,
                            builder='_filename',
                            lazy=True)
    storage = ElkAttribute(mode='rw', builder='_storage', lazy=True)
    cache = attr(mode='rw', type=dict, builder='_cache', lazy=True)

    def _cache(self):
        return dict()

    def _filename(self):
        return os.path.dirname(
            os.path.abspath(
                inspect.getfile(inspect.currentframe()))) \
                    + '/../../../data/memory.db'

    def _storage(self):
        print(("loading '{}' memory file".format(self.filename)))
        c = sqlite3.connect(self.filename)
        c.execute('''CREATE TABLE IF NOT EXISTS memory
             (
             date text,
             noun text,
             verb text,
             place text
             )''')
        c.commit()
        return c

    def create_cursor(self):
        return self.storage.cursor()

    def remember(self, fields):
        place = fields['place'] or ""
        noun = fields['noun'] or ""
        verb = fields['verb'] or ""

        t = datetime.now()
        if place in self.cache:
            if noun in self.cache[place]:
                if verb in self.cache[place][noun]:
                    delay = (t - self.cache[place][noun][verb]).total_seconds()
                    if delay < 60 * 5:  # 5 minutes
                        return False
            else:
                self.cache[place][noun] = dict()
        else:
            self.cache[place] = dict()
            self.cache[place][noun] = dict()

        self.cache[place][noun][verb] = t
        log.info("logging at {} {} {} {}".format(
            place, t.strftime("%d %b %Y %H:%M:%S"), noun, verb))
        c = self.create_cursor()
        record = ("date('now')", place, noun, verb)
        c.execute(
            '''INSERT INTO memory(date,place,noun,verb)
            VALUES(?,?,?,?)''', record)
        self.storage.commit()
        return True

    def close(self):
        self.storage = None

    def query(self, fields, conditions, order=None, amount=0):
        c = self.create_cursor()
        select = "SELECT"
        select += " "
        if fields:
            select += ', '.join(fields)
        else:
            select += '*'
        select += ' FROM memory'
        if conditions:
            wheres = []
            for name, value in list(conditions.items()):
                wheres.append(" %s == '%s'" % (name, value))
            select += " WHERE " + " AND ".join(wheres)
        if order:
            select += " ORDER BY " + ", ".join(conditions)
        if amount:
            select += " LIMIT " + str(amount)
        log.debug("quering " + select)
        print(("quering " + select))
        return c.execute(select)

    def query_one(self, field, conditions, order=None):
        result = self.query([field], conditions, order, 1)
        item = next(result)
        if item:
            return item[0]
        return None