[mousetrap/gnome3-wip: 65/240] Refactor into byte-sized methods that do one thing.



commit 4144587a3fbb56525fe3f7e11981e715f5db0c3d
Author: Stoney Jackson <dr stoney gmail com>
Date:   Wed Jun 11 10:22:36 2014 -0400

    Refactor into byte-sized methods that do one thing.

 run.py |  120 +++++++++++++++++++++++++++++++++++----------------------------
 1 files changed, 67 insertions(+), 53 deletions(-)
---
diff --git a/run.py b/run.py
index ec64705..2fdb856 100644
--- a/run.py
+++ b/run.py
@@ -6,80 +6,94 @@ from mousetrap.vision import Camera, HaarLoader, ImageConverter
 
 class TrackerSample(object):
 
-    def run(self):
-        # Initialize the camera and get the frame
-
+    def __init__(self):
+        self.camera = None
+        self.cascades = None
+        self.image_grayscale = None
+        self.faces = None
+        self.face = None
+        self.noses = None
+        self.nose = None
+        self.initialize_camera()
+        self.initialize_cascades()
+
+    def initialize_camera(self):
         SEARCH_FOR_DEVICE = -1
         DEVICE_INDEX = SEARCH_FOR_DEVICE
         CAMERA_WIDTH = 400
         CAMERA_HEIGHT = 300
-
-        camera = Camera(
+        self.camera = Camera(
                 device_index=SEARCH_FOR_DEVICE,
                 width=CAMERA_WIDTH,
                 height=CAMERA_HEIGHT)
 
-        image = camera.read_image()
-
-        # Convert the image to grayscale
-
-        gray = ImageConverter.rgb_to_grayscale(image)
-
-        # Import the haar cascades
-
-        cascades = {
+    def initialize_cascades(self):
+        self.cascades = {
                 "face": HaarLoader.from_name("face"),
                 "nose": HaarLoader.from_name("nose")
                 }
 
-        # Detect faces using the cascade
-
+    def run(self):
+        self.read_grayscale_image()
+        self.detect_faces()
+        self.exit_if_no_faces_detected()
+        self.unpack_first_face()
+        self.extract_face_image()
+        self.detect_noses()
+        self.exit_if_no_noses_detected()
+        self.unpack_first_nose()
+        self.calculate_center_of_nose()
+        print self.nose
+
+    def read_grayscale_image(self):
+        image = self.camera.read_image()
+        self.image_grayscale = ImageConverter.rgb_to_grayscale(image)
+
+    def detect_faces(self):
         # Use a 1.5 scale to ensure the head is always found
         SCALE = 1.5
-
         # Requiring 5 neighbors helps discard invalid faces
         REQUIRED_NEIGHBORS = 5
+        self.faces = self.cascades["face"].detectMultiScale(
+                self.image_grayscale, SCALE, REQUIRED_NEIGHBORS)
 
-        faces = cascades["face"].detectMultiScale(gray, SCALE, REQUIRED_NEIGHBORS)
-
-        # Fail early if there were no faces
-
-        if not len(faces):
-            sys.exit(1)
-
-        # Unpack the detected face into a more readable dictionary
+    def exit_if_no_faces_detected(self):
+        if len(self.faces) == 0:
+            raise Exception('No faces detected')
 
-        face = {}
-        face["x"], face["y"], face["width"], face["height"] = faces[0]
+    def unpack_first_face(self):
+        self.face = dict(zip(['x', 'y', 'width', 'height'], self.faces[0]))
 
-        # Get the smaller image for the detected face
+    def extract_face_image(self):
+        f = self.face
+        from_y = f['y']
+        to_y = f['y'] + f['height']
+        from_x = f['x']
+        to_x = f['x'] + f['width']
+        f["image"] = self.image_grayscale[from_y:to_y, from_x:to_x]
 
-        face["image"] = gray[face["y"]:face["y"] + face["height"],
-                face["x"]:face["x"] + face["width"]]
-
-        # Detect noses using the cascade
-
-        noses = cascades["nose"].detectMultiScale(face["image"], 1.3, 5)
-
-        # Fail early is there are no noses
-
-        if not len(noses):
-            sys.exit(1)
-
-        # Unpack the nose
-
-        nose = {}
-        nose["x"], nose["y"], nose["width"], nose["height"] = noses[0]
-
-        # Determine the central point of the nose
-        # This is done relative to the face
-        # It should probably be done relative to the entire picture
-
-        nose["center"] = {
-                "x": (nose["x"] + nose["width"]) / 2,
-                "y": (nose["y"] + nose["height"]) / 2,
+    def detect_noses(self):
+        # Use a 1.5 scale to ensure the head is always found
+        SCALE = 1.5
+        # Requiring 5 neighbors helps discard invalid faces
+        REQUIRED_NEIGHBORS = 5
+        self.noses = self.cascades["nose"].detectMultiScale(
+                self.face["image"], SCALE, REQUIRED_NEIGHBORS)
+
+    def exit_if_no_noses_detected(self):
+        if len(self.noses) == 0:
+            raise Exception('No noses detected.')
+
+    def unpack_first_nose(self):
+        self.nose = dict(zip(['x', 'y', 'width', 'height'], self.noses[0]))
+
+    def calculate_center_of_nose(self):
+        # FIXME: This is done relative to the face; it should probably be done
+        # relative to the entire picture
+        self.nose["center"] = {
+                "x": (self.nose["x"] + self.nose["width"]) / 2,
+                "y": (self.nose["y"] + self.nose["height"]) / 2,
                 }
 
-        print nose
 
 TrackerSample().run()


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