[mousetrap/gnome3-wip: 68/240] Move FeatureDetector and NoseLocator into vision, and run.py into mousetrap.nose_locator_sample.



commit 5324632af676c6388e1eabdc30243c679e7aa5f3
Author: Stoney Jackson <dr stoney gmail com>
Date:   Wed Jun 11 17:00:42 2014 -0400

    Move FeatureDetector and NoseLocator into vision, and run.py into mousetrap.nose_locator_sample.

 run.py                               |   95 ----------------------------------
 src/mousetrap/nose_locator_sample.py |   27 ++++++++++
 src/mousetrap/vision.py              |   70 +++++++++++++++++++++++++
 3 files changed, 97 insertions(+), 95 deletions(-)
---
diff --git a/src/mousetrap/nose_locator_sample.py b/src/mousetrap/nose_locator_sample.py
new file mode 100644
index 0000000..cbd60bd
--- /dev/null
+++ b/src/mousetrap/nose_locator_sample.py
@@ -0,0 +1,27 @@
+from mousetrap.vision import Camera, ImageConverter, NoseLocator
+
+
+class NoseLocatorSample(object):
+    def __init__(self):
+        self._camera = None
+        self._nose_locator = NoseLocator()
+        self._initialize_camera()
+
+    def _initialize_camera(self):
+        search_for_device = -1
+        self._camera = Camera(
+                device_index=search_for_device,
+                width=400, height=300)
+
+    def run(self):
+        image = self._read_grayscale_image()
+        nose = self._nose_locator.locate(image)
+        print nose
+
+    def _read_grayscale_image(self):
+        image = self._camera.read_image()
+        return ImageConverter.rgb_to_grayscale(image)
+
+
+if __name__ == '__main__':
+    NoseLocatorSample().run()
diff --git a/src/mousetrap/vision.py b/src/mousetrap/vision.py
index c2f7fdd..5c776a9 100644
--- a/src/mousetrap/vision.py
+++ b/src/mousetrap/vision.py
@@ -85,3 +85,73 @@ class HaarLoader(object):
                 HaarLoader._haar_cache[cache_name] = haar
 
         return haar
+
+
+class NoseLocator(object):
+    def __init__(self):
+        self._face_detector = FeatureDetector(
+                'face', scale_factor=1.5, min_neighbors=5)
+        self._nose_detector = FeatureDetector(
+                'nose', scale_factor=1.3, min_neighbors=5)
+
+    def locate(self, image_grayscale):
+        face = self._face_detector.detect(image_grayscale)
+        nose = self._nose_detector.detect(face['image'])
+        return {
+                'x': face['x'] + nose['center']['x'],
+                'y': face['y'] + nose['center']['y'],
+                }
+
+
+class FeatureDetector(object):
+    def __init__(self, name, scale_factor=1.1, min_neighbors=3):
+        '''
+        name - name of feature to detect
+
+        scale_factor - how much the image size is reduced at each image scale
+                while searching. Default 1.1.
+
+        min_neighbors - how many neighbors each candidate rectangle should have
+                to retain it. Default 3.
+        '''
+        self._name = name
+        self._single = None
+        self._plural = None
+        self._image_grayscale = None
+        self._cascade = HaarLoader.from_name(name)
+        self._scale_factor = scale_factor
+        self._min_neighbors = min_neighbors
+
+    def detect(self, image_grayscale):
+        self._image_grayscale = image_grayscale
+        self._detect_plural()
+        self._exit_if_none_detected()
+        self._unpack_first()
+        self._extract_image()
+        self._calculate_center()
+        return self._single
+
+    def _detect_plural(self):
+        self._plural = self._cascade.detectMultiScale(
+                self._image_grayscale, self._scale_factor, self._min_neighbors)
+
+    def _exit_if_none_detected(self):
+        if len(self._plural) == 0:
+            raise Exception('No ' + self._name + 's detected.')
+
+    def _unpack_first(self):
+        self._single = dict(zip(['x', 'y', 'width', 'height'], self._plural[0]))
+
+    def _calculate_center(self):
+        self._single["center"] = {
+                "x": (self._single["x"] + self._single["width"]) / 2,
+                "y": (self._single["y"] + self._single["height"]) / 2,
+                }
+
+    def _extract_image(self):
+        single = self._single
+        from_y = single['y']
+        to_y = single['y'] + single['height']
+        from_x = single['x']
+        to_x = single['x'] + single['width']
+        single["image"] = self._image_grayscale[from_y:to_y, from_x:to_x]


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]