diff --git a/.coveragerc b/.coveragerc index 41794b810f4..9656508982a 100644 --- a/.coveragerc +++ b/.coveragerc @@ -237,6 +237,8 @@ omit = homeassistant/components/foursquare.py homeassistant/components/hdmi_cec.py homeassistant/components/ifttt.py + homeassistant/components/image_processing/dlib_face_detect.py + homeassistant/components/image_processing/dlib_face_identify.py homeassistant/components/joaoapps_join.py homeassistant/components/keyboard.py homeassistant/components/keyboard_remote.py diff --git a/homeassistant/components/image_processing/dlib_face_detect.py b/homeassistant/components/image_processing/dlib_face_detect.py new file mode 100644 index 00000000000..5877535d3e0 --- /dev/null +++ b/homeassistant/components/image_processing/dlib_face_detect.py @@ -0,0 +1,71 @@ +""" +Component that will help set the dlib face detect processing. + +For more details about this component, please refer to the documentation at +https://home-assistant.io/components/image_processing.dlib_face_detect/ +""" +import logging +import io + +from homeassistant.core import split_entity_id +# pylint: disable=unused-import +from homeassistant.components.image_processing import PLATFORM_SCHEMA # noqa +from homeassistant.components.image_processing import ( + CONF_SOURCE, CONF_ENTITY_ID, CONF_NAME) +from homeassistant.components.image_processing.microsoft_face_identify import ( + ImageProcessingFaceEntity) + +REQUIREMENTS = ['face_recognition==0.1.14'] + +_LOGGER = logging.getLogger(__name__) + + +def setup_platform(hass, config, add_devices, discovery_info=None): + """Set up the Microsoft Face detection platform.""" + entities = [] + for camera in config[CONF_SOURCE]: + entities.append(DlibFaceDetectEntity( + camera[CONF_ENTITY_ID], camera.get(CONF_NAME) + )) + + add_devices(entities) + + +class DlibFaceDetectEntity(ImageProcessingFaceEntity): + """Dlib Face API entity for identify.""" + + def __init__(self, camera_entity, name=None): + """Initialize Dlib.""" + super().__init__() + + self._camera = camera_entity + + if name: + self._name = name + else: + self._name = "Dlib Face {0}".format( + split_entity_id(camera_entity)[1]) + + @property + def camera_entity(self): + """Return camera entity id from process pictures.""" + return self._camera + + @property + def name(self): + """Return the name of the entity.""" + return self._name + + def process_image(self, image): + """Process image.""" + # pylint: disable=import-error + import face_recognition + + fak_file = io.BytesIO(image) + fak_file.name = "snapshot.jpg" + fak_file.seek(0) + + image = face_recognition.load_image_file(fak_file) + face_locations = face_recognition.face_locations(image) + + self.process_faces(face_locations, len(face_locations)) diff --git a/homeassistant/components/image_processing/dlib_face_identify.py b/homeassistant/components/image_processing/dlib_face_identify.py new file mode 100644 index 00000000000..a0f50796a9f --- /dev/null +++ b/homeassistant/components/image_processing/dlib_face_identify.py @@ -0,0 +1,95 @@ +""" +Component that will help set the dlib face detect processing. + +For more details about this component, please refer to the documentation at +https://home-assistant.io/components/image_processing.dlib_face_identify/ +""" +import logging +import io + +import voluptuous as vol + +from homeassistant.core import split_entity_id +from homeassistant.components.image_processing import ( + PLATFORM_SCHEMA, CONF_SOURCE, CONF_ENTITY_ID, CONF_NAME) +from homeassistant.components.image_processing.microsoft_face_identify import ( + ImageProcessingFaceEntity) +import homeassistant.helpers.config_validation as cv + +REQUIREMENTS = ['face_recognition==0.1.14'] + +_LOGGER = logging.getLogger(__name__) + +ATTR_NAME = 'name' +CONF_FACES = 'faces' + +PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({ + vol.Required(CONF_FACES): {cv.string: cv.isfile}, +}) + + +def setup_platform(hass, config, add_devices, discovery_info=None): + """Set up the Microsoft Face detection platform.""" + entities = [] + for camera in config[CONF_SOURCE]: + entities.append(DlibFaceIdentifyEntity( + camera[CONF_ENTITY_ID], config[CONF_FACES], camera.get(CONF_NAME) + )) + + add_devices(entities) + + +class DlibFaceIdentifyEntity(ImageProcessingFaceEntity): + """Dlib Face API entity for identify.""" + + def __init__(self, camera_entity, faces, name=None): + """Initialize Dlib.""" + # pylint: disable=import-error + import face_recognition + super().__init__() + + self._camera = camera_entity + + if name: + self._name = name + else: + self._name = "Dlib Face {0}".format( + split_entity_id(camera_entity)[1]) + + self._faces = {} + for name, face_file in faces.items(): + image = face_recognition.load_image_file(face_file) + self._faces[name] = face_recognition.face_encodings(image)[0] + + @property + def camera_entity(self): + """Return camera entity id from process pictures.""" + return self._camera + + @property + def name(self): + """Return the name of the entity.""" + return self._name + + def process_image(self, image): + """Process image.""" + # pylint: disable=import-error + import face_recognition + + fak_file = io.BytesIO(image) + fak_file.name = "snapshot.jpg" + fak_file.seek(0) + + image = face_recognition.load_image_file(fak_file) + unknowns = face_recognition.face_encodings(image) + + found = [] + for unknown_face in unknowns: + for name, face in self._faces.items(): + result = face_recognition.compare_faces([face], unknown_face) + if result[0]: + found.append({ + ATTR_NAME: name + }) + + self.process_faces(found, len(unknowns)) diff --git a/homeassistant/components/image_processing/microsoft_face_detect.py b/homeassistant/components/image_processing/microsoft_face_detect.py index e12c2d1d646..5c4daec1067 100644 --- a/homeassistant/components/image_processing/microsoft_face_detect.py +++ b/homeassistant/components/image_processing/microsoft_face_detect.py @@ -22,8 +22,6 @@ DEPENDENCIES = ['microsoft_face'] _LOGGER = logging.getLogger(__name__) -EVENT_IDENTIFY_FACE = 'detect_face' - SUPPORTED_ATTRIBUTES = [ ATTR_AGE, ATTR_GENDER, diff --git a/requirements_all.txt b/requirements_all.txt index 762c9c77f56..c6f56e3a9e0 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -174,6 +174,10 @@ envirophat==0.0.6 # homeassistant.components.climate.honeywell evohomeclient==0.2.5 +# homeassistant.components.image_processing.dlib_face_detect +# homeassistant.components.image_processing.dlib_face_identify +# face_recognition==0.1.14 + # homeassistant.components.sensor.fastdotcom fastdotcom==0.0.1 diff --git a/script/gen_requirements_all.py b/script/gen_requirements_all.py index 1ac18ea0705..4d08ff349a0 100755 --- a/script/gen_requirements_all.py +++ b/script/gen_requirements_all.py @@ -23,7 +23,8 @@ COMMENT_REQUIREMENTS = ( 'pycups', 'python-eq3bt', 'avion', - 'decora' + 'decora', + 'face_recognition' ) IGNORE_PACKAGES = (