Advertisement
Guest User

Untitled

a guest
Apr 22nd, 2014
92
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 10.91 KB | None | 0 0
  1. import dbus
  2. import dbus.decorators
  3. import dbus.glib
  4. import cv2.cv as cv
  5. import time
  6. import sys
  7.  
  8. class MotionDetectorInstantaneous():
  9.  
  10.     def onChange(self, val): #callback when the user change the detection threshold
  11.         self.threshold = val
  12.  
  13.     def __init__(self, threshold=8, showWindows=True, callback=None):
  14.  
  15.         self.callback = callback
  16.         self.writer = None
  17.         self.font = None
  18.         self.show = showWindows #Either or not show the 2 windows
  19.         self.frame = None
  20.  
  21.         self.verbose = True
  22.  
  23.         self.capture = cv.CaptureFromCAM(0)
  24.         self.frame = cv.QueryFrame(self.capture) #Take a frame to init recorder
  25.  
  26.         self.frame1gray = cv.CreateMat(self.frame.height, self.frame.width, cv.CV_8U) #Gray frame at t-1
  27.         cv.CvtColor(self.frame, self.frame1gray, cv.CV_RGB2GRAY)
  28.  
  29.         #Will hold the thresholded result
  30.         self.res = cv.CreateMat(self.frame.height, self.frame.width, cv.CV_8U)
  31.  
  32.         self.frame2gray = cv.CreateMat(self.frame.height, self.frame.width, cv.CV_8U) #Gray frame at t
  33.  
  34.         self.width = self.frame.width
  35.         self.height = self.frame.height
  36.         self.nb_pixels = self.width * self.height
  37.         self.threshold = threshold
  38.         self.isRecording = False
  39.         self.trigger_time = 0 #Hold timestamp of the last detection
  40.  
  41.         if showWindows:
  42.             cv.NamedWindow("MoveDetection")
  43.             cv.CreateTrackbar("Detection treshold: ", "MoveDetection", self.threshold, 100, self.onChange)
  44.  
  45.     def processImage(self, frame):
  46.         cv.CvtColor(frame, self.frame2gray, cv.CV_RGB2GRAY)
  47.  
  48.         #Absdiff to get the difference between to the frames
  49.         cv.AbsDiff(self.frame1gray, self.frame2gray, self.res)
  50.  
  51.         #Remove the noise and do the threshold
  52.         cv.Smooth(self.res, self.res, cv.CV_BLUR, 5,5)
  53.         cv.MorphologyEx(self.res, self.res, None, None, cv.CV_MOP_OPEN)
  54.         cv.MorphologyEx(self.res, self.res, None, None, cv.CV_MOP_CLOSE)
  55.         cv.Threshold(self.res, self.res, 10, 255, cv.CV_THRESH_BINARY_INV)
  56.  
  57.     def somethingHasMoved(self):
  58.         nb=0 #Will hold the number of black pixels
  59.  
  60.         for x in range(self.height): #Iterate the hole image
  61.             for y in range(self.width):
  62.                 if self.res[x,y] == 0.0: #If the pixel is black keep it
  63.                     nb += 1
  64.         avg = (nb*100.0)/self.nb_pixels #Calculate the average of black pixel in the image
  65.  
  66.         if avg > self.threshold:#If over the ceiling trigger the alarm
  67.             return True
  68.         else:
  69.             return False
  70.  
  71.     def iteration(self):
  72.  
  73.         curframe = cv.QueryFrame(self.capture)
  74.         self.processImage(curframe) #Process the image
  75.  
  76.         if self.somethingHasMoved():
  77.             if self.callback:
  78.                 self.callback()
  79.  
  80.         if self.show:
  81.             cv.ShowImage("MoveDetection", curframe)
  82.             #cv.ShowImage("Res", self.res)
  83.  
  84.         cv.Copy(self.frame2gray, self.frame1gray)
  85.         c = cv.WaitKey(1) % 0x100
  86.  
  87.          #Break if user enters 'Esc'.
  88.         if c == 27 or c == 10:
  89.             return True
  90.  
  91.  
  92. class FaceActivityMonitor():
  93.  
  94.     def __init__(self, appear_callback, disappear_callback, capture=None):
  95.  
  96.         self.init_variables()
  97.  
  98.         self.init_face_detect(capture)
  99.  
  100.         self.appear_callback = appear_callback
  101.         self.disappear_callback = disappear_callback
  102.  
  103.     def cleanup(self):
  104.         if self.show:
  105.             cv.DestroyWindow("FaceDetection")
  106.  
  107.     def init_variables(self):
  108.         self.cascade_name     = "/usr/share/opencv/haarcascades/haarcascade_frontalface_alt.xml"
  109.         self.device           = 0
  110.         self.show             = True
  111.         self.verbose          = False
  112.         self.face_threshold   = 2
  113.         self.noface_threshold = 5
  114.         # Parameters for haar detection
  115.         # From the API:
  116.         # The default parameters (scale_factor=1.1, min_neighbors=3, flags=0) are tuned
  117.         # for accurate yet slow object detection. For a faster operation on real video
  118.         # images the settings are:
  119.         # scale_factor=1.2, min_neighbors=2, flags=CV_HAAR_DO_CANNY_PRUNING,
  120.         # min_size=<minimum possible face size
  121.         self.min_size         = (50, 50)
  122.         self.image_scale      = 1.2
  123.         self.haar_scale       = 1.2
  124.         self.min_neighbors    = 2
  125.         self.haar_flags       = cv.CV_HAAR_DO_CANNY_PRUNING
  126.  
  127.         self.cascase  = None
  128.         self.capture  = None
  129.         self.storage = None
  130.         self.last_time = 0
  131.         self.frame_copy = None
  132.         self.count_face = 0
  133.         self.count_noface = 0
  134.  
  135.     def init_face_detect(self, capture):
  136.         # the OpenCV API says this function is obsolete, but we can't
  137.         # cast the output of cvLoad to a HaarClassifierCascade, so use this anyways
  138.         # the size parameter is ignored
  139.         #self.cascade = cv.LoadHaarClassifierCascade(self.cascade_name, (1, 1))
  140.         self.cascade = cv.Load(self.cascade_name)
  141.  
  142.         if not self.cascade:
  143.             print "ERROR: Could not load classifier cascade"
  144.             sys.exit(-1)
  145.  
  146.         if not capture:
  147.             self.capture = cv.CreateCameraCapture(int(self.device))
  148.         else:
  149.             self.capture = capture
  150.  
  151.         self.storage = cv.CreateMemStorage(0)
  152.  
  153.         if self.show:
  154.             cv.NamedWindow("FaceDetection", 1)
  155.  
  156.     def detect_and_draw(self, image):
  157.  
  158.         gray = cv.CreateImage((image.width, image.height), 8, 1)
  159.  
  160.         small_image = cv.CreateImage((cv.Round(image.width/self.image_scale),
  161.                                            cv.Round(image.height/self.image_scale)),
  162.                                     8, 1)
  163.  
  164.         cv.CvtColor(image, gray, cv.CV_BGR2GRAY)
  165.         cv.Resize(gray, small_image, cv.CV_INTER_LINEAR)
  166.         cv.EqualizeHist(small_image, small_image)
  167.  
  168.         #cv.ClearMemStorage(self.storage)
  169.  
  170.         faces = cv.HaarDetectObjects(small_image,
  171.                                     self.cascade,
  172.                                     self.storage,
  173.                                     self.haar_scale,
  174.                                     self.min_neighbors,
  175.                                     self.haar_flags,
  176.                                     self.min_size)
  177.         if self.show and faces:
  178.             for ((x, y, w, h), n) in faces:
  179.                 pt1 = (int(x*self.image_scale), int(y*self.image_scale))
  180.                 pt2 = (int((x+w)*self.image_scale), int((y+h)*self.image_scale))
  181.                 cv.Rectangle(image, pt1, pt2, cv.CV_RGB(255,0,0), 3, 8, 0)
  182.  
  183.  
  184.         cv.ShowImage("FaceDetection", image)
  185.  
  186.         return len(faces) > 0
  187.  
  188.  
  189.     def iteration(self):
  190.  
  191.         frame = cv.QueryFrame(self.capture)
  192.         if not frame:
  193.             return False
  194.  
  195.         if frame.origin == cv.IPL_ORIGIN_TL:
  196.             user_detected = self.detect_and_draw(frame)
  197.         else:
  198.             if not self.frame_copy:
  199.                 self.frame_copy = cv.CreateImage((frame.width,frame.height),
  200.                                                 cv.IPL_DEPTH_8U, frame.nChannels)
  201.  
  202.             cv.Flip(frame, self.frame_copy, 0)
  203.             user_detected = self.detect_and_draw(self.frame_copy)
  204.  
  205.         self.inform_workrave(user_detected)
  206.  
  207.         c = cv.WaitKey(1) % 0x100
  208.         if c == 27 or c == 10:
  209.             return True
  210.  
  211.  
  212.     def inform_workrave(self, user_detected):
  213.  
  214.         if user_detected:
  215.             self.count_face += 1
  216.             self.count_noface = 0
  217.         else:
  218.             self.count_noface += 1
  219.             self.count_face = 0
  220.  
  221.         if self.count_face >= self.face_threshold:
  222.  
  223.             if self.verbose and self.count_face == self.face_threshold:
  224.                 print "Reporting user presence"
  225.  
  226.             now = time.time()
  227.             if now > self.last_time + 5:
  228.                 self.appear_callback()
  229.                 self.last_time = now
  230.  
  231.         if self.count_noface == self.noface_threshold:
  232.             if self.verbose:
  233.                 print "Reporting user absence"
  234.             self.disappear_callback()
  235.  
  236.  
  237. class RingWorkrave():
  238.  
  239.     def __init__(self):
  240.         self.verbose = True
  241.  
  242.         self.motion_detector = MotionDetectorInstantaneous(callback=self.move)
  243.         self.face_detection = FaceActivityMonitor(self.face_appeared, self.disappear, self.motion_detector.capture)
  244.  
  245.         self.ignore = False
  246.  
  247.         self.init_dbus()
  248.  
  249.     def init_dbus(self):
  250.         bus = dbus.SessionBus()
  251.         obj = bus.get_object("org.workrave.Workrave", "/org/workrave/Workrave/Core")
  252.  
  253.         self.workrave = dbus.Interface(obj, "org.workrave.CoreInterface")
  254.  
  255.         self.workrave.connect_to_signal("MicrobreakChanged",
  256.                                         self.microbreak_signal, sender_keyword='sender')
  257.         self.workrave.connect_to_signal("RestbreakChanged",
  258.                                         self.restbreak_signal, sender_keyword='sender')
  259.         self.workrave.connect_to_signal("DailylimitChanged",
  260.                                         self.dailylimit_signal, sender_keyword='sender')
  261.  
  262.     def move(self):
  263.         if self.ignore:
  264.             return
  265.  
  266.         if self.verbose:
  267.             print "Motion detected"
  268.  
  269.         self.workrave.ReportActivity("facedetect", True)
  270.  
  271.     def face_appeared(self):
  272.         if self.ignore:
  273.             return
  274.  
  275.         if self.verbose:
  276.             print "Face detected"
  277.  
  278.         self.workrave.ReportActivity("facedetect", True)
  279.  
  280.     def disappear(self):
  281.         if self.ignore:
  282.             return
  283.  
  284.         if self.verbose:
  285.             print "Face disappeared"
  286.  
  287.         self.workrave.ReportActivity("facedetect", False)
  288.  
  289.     def microbreak_signal(self, progress, sender=None):
  290.         self.break_signal("microbreak", progress)
  291.  
  292.     def restbreak_signal(self, progress, sender=None):
  293.         self.break_signal("restbreak", progress)
  294.  
  295.     def dailylimit_signal(self, progress, sender=None):
  296.         self.break_signal("dailylimit", progress)
  297.  
  298.     def break_signal(self, breakid, progress, sender=None):
  299.         if progress != "none":
  300.             self.ignore = True
  301.             self.workrave.ReportActivity("facedetect", False)
  302.         else:
  303.             self.ignore = False
  304.  
  305.         if self.verbose:
  306.             if progress == "prelude":
  307.                 print "Ignoring user presence: %s warning" % breakid
  308.             elif progress == "break":
  309.                 print "Ignoring user presence: %s started" % breakid
  310.             elif progress == "none":
  311.                 print "Resuming presence monitoring: Break %s idle" % breakid
  312.             else:
  313.                 print "Unknown progress for %s: %s" % (breakid, progress)
  314.  
  315.     def run(self):
  316.         while True:
  317.  
  318.             if self.motion_detector:
  319.                 if self.motion_detector.iteration():
  320.                     break
  321.  
  322.             if self.face_detection:
  323.                 if self.face_detection.iteration():
  324.                     break
  325.  
  326. if __name__ == "__main__":
  327.     ring = RingWorkrave()
  328.     ring.run()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement