Advertisement
siketh

Motion Detection

Jun 29th, 2015
492
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 4.37 KB | None | 0 0
  1. #!/usr/bin/env python
  2.  
  3. import cv2, rospy, roslib, tf
  4. roslib.load_manifest('asr')
  5. import sys
  6. from std_msgs.msg import String
  7. from sensor_msgs.msg import Image
  8. from cv_bridge import CvBridge, CvBridgeError
  9.  
  10.  
  11. # motion tracking function which detects largest contour in thresholded/blurred image and draws a bounding target
  12. # around it
  13. def track_motion(t_b_image, bgr_img):
  14.  
  15.     # find contours in the image
  16.     image, contours, hierarchy = cv2.findContours(t_b_image, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
  17.  
  18.     # if countours exist, there there is motion in the image
  19.     if len(contours) > 0:
  20.  
  21.         # the largest contour is the best candidate for the moving object, this is the last item in the
  22.         # contour vector
  23.         largest_con = contours[-1]
  24.  
  25.         # set parameters for the bounding circle
  26.         (x, y), radius = cv2.minEnclosingCircle(largest_con)
  27.         center = (int(x), int(y))
  28.         text_center = (int(x-125), int(y+100))
  29.         radius = int(radius)
  30.  
  31.         # draw crosshair on image with text indicating the centroid of motion
  32.         bgr_img = cv2.circle(bgr_img, center, 50, (0, 255, 0), 2)
  33.         bgr_img = cv2.line(bgr_img, center, (int(x), int(y-75)), (0, 255, 0), 2)
  34.         bgr_img = cv2.line(bgr_img, center, (int(x), int(y+75)), (0, 255, 0), 2)
  35.         bgr_img = cv2.line(bgr_img, center, (int(x-75), int(y)), (0, 255, 0), 2)
  36.         bgr_img = cv2.line(bgr_img, center, (int(x+75), int(y)), (0, 255, 0), 2)
  37.         bgr_img = cv2.putText(bgr_img, "MOTION DETECTED: " + str(center), text_center, 1, 1, (0, 255, 0), 2)
  38.  
  39.     # return the image
  40.     return bgr_img
  41.  
  42.  
  43. # perform differential imaging
  44. def get_diff_img(t0, t1, t2):
  45.     d1 = cv2.absdiff(t2, t1)
  46.     d2 = cv2.absdiff(t1, t0)
  47.     return cv2.bitwise_and(d1, d2)
  48.  
  49.  
  50. def callback(data):
  51.     global camera_img, image_sub
  52.  
  53.     try:
  54.         bridge = CvBridge()
  55.         camera_img = bridge.imgmsg_to_cv2(data, "bgr8")
  56.         image_sub.unregister()
  57.     except CvBridgeError, e:
  58.         print e
  59.  
  60.  
  61. def motion_detector():
  62.     global camera_img, image_sub
  63.  
  64.     bridge = CvBridge()
  65.     camera_img = "EMPTY"
  66.     threshold = 30
  67.     blur = (10, 10)
  68.  
  69.     rospy.init_node('motion_detector', anonymous=False)
  70.  
  71.     image_sub = rospy.Subscriber("/camera/rgb/image_color", Image, callback, queue_size=10)
  72.     image_pub = rospy.Publisher("/motion_image", Image, queue_size=10)
  73.  
  74.     rate = rospy.Rate(120) # 120hz
  75.  
  76.     while camera_img is "EMPTY":
  77.         print "Waiting for camera frames..."
  78.  
  79.     # grab 3 identical images to initialize
  80.     t_minus = cv2.cvtColor(camera_img, cv2.COLOR_BGR2GRAY)
  81.     t = cv2.cvtColor(camera_img, cv2.COLOR_BGR2GRAY)
  82.     t_plus = cv2.cvtColor(camera_img, cv2.COLOR_BGR2GRAY)
  83.  
  84.     while not rospy.is_shutdown():
  85.  
  86.         # get differential image
  87.         diff_img = get_diff_img(t_minus, t, t_plus)
  88.  
  89.         # perform thresholding and blurring
  90.         retrieved, thresh_img = cv2.threshold(diff_img, threshold, 255, cv2.THRESH_BINARY)
  91.         blur_img = cv2.blur(thresh_img, blur)
  92.  
  93.         # if thresholding failed something went wrong, warn and exit
  94.         if not retrieved:
  95.             print "Unable to perform thresholding on image"
  96.             break
  97.  
  98.         # perform thresholding again on blurred image
  99.         status, blur_thresh_img = cv2.threshold(blur_img, threshold, 255, cv2.THRESH_BINARY)
  100.  
  101.         # create motion image
  102.         motion_img = track_motion(blur_thresh_img, camera_img)
  103.  
  104.         # show/publish motion image
  105.         try:
  106.             img = bridge.cv2_to_imgmsg(motion_img, "bgr8")
  107.             image_pub.publish(img)
  108.         except CvBridgeError, e:
  109.             print e
  110.  
  111.         #cv2.imshow("MOTION TRACKING", motion_img)
  112.        # cv2.waitKey(3)
  113.  
  114.         # DEBUG
  115.         #cv2.imshow("BGR IMAGE", img)
  116.         #cv2.imshow("DIFF IMAGE", diff_img)
  117.         #cv2.imshow("THRESH IMAGE", thresh_img)
  118.         #cv2.imshow("BLUR IMAGE", blur_img)
  119.         #cv2.imshow("BLUR + THRESH IMAGE", blur_thresh_img)
  120.  
  121.         # retrieve a bgr image from the kinect
  122.         image_sub = rospy.Subscriber("camera/rgb/image_color", Image, callback, queue_size=10)
  123.  
  124.         # increment the images
  125.         t_minus = t
  126.         t = t_plus
  127.         t_plus = cv2.cvtColor(camera_img, cv2.COLOR_BGR2GRAY)
  128.  
  129.     rate.sleep()
  130.  
  131. if __name__ == '__main__':
  132.     try:
  133.         motion_detector()
  134.     except rospy.ROSInterruptException:
  135.         pass
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement