Advertisement
Guest User

Untitled

a guest
Jul 17th, 2019
115
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 4.00 KB | None | 0 0
  1. import cv2
  2. from cv_bridge import CvBridge, CvBridgeError
  3. import rospy
  4. from sensor_msgs.msg import Image
  5.  
  6. """
  7. Starter code for an image processing node. Subscribes to the downward camera
  8. and publishes a processed cv image (i.e. colorized, overlayed with a detected line)
  9. This node is not meant to be a full node that you will use in your final line tracking
  10. solution, but it will teach you key concepts that you will need for line following
  11. """
  12.  
  13. class ImageToCV:
  14.     def __init__(self):
  15.         # A subscriber to the topic '/aero_downward_camera/image'. self.image_sub_cb is called when a message is recieved
  16.         self.camera_sub = rospy.Subscriber("/aero_downward_camera/image", Image, self.image_cb)
  17.  
  18.         # A publisher which will publish a parametrization of the detected line to the topic '/image_to_cv/processed'
  19.         self.image_pub = rospy.Publisher("/image_to_cv/processed", Image, queue_size=1)
  20.         self.bridge = CvBridge()
  21.  
  22.     def image_cb(self, msg):
  23.         """
  24.        Callback function which is called when a new message of type Image is recieved by self.camera_sub.
  25.  
  26.            Args:
  27.                - msg = ROS Image message in 8UC1 format
  28.  
  29.            Returns: NA
  30.        """
  31.         try:
  32.             cv_image = self.bridge.imgmsg_to_cv2(msg, "8UC1")
  33.             self.process(cv_image)
  34.         except CvBridgeError as e:
  35.             print(e)
  36.  
  37.     def calculate_regression(points): # input is the result of np.argwhere
  38.         # convert points to float
  39.    
  40.         #(see astype, https://docs.scipy.org/doc/numpy/reference/generated/numpy.ndarray.astype.html)
  41.         points = points.astype(float)
  42.    
  43.         #num_points = points.shape[0]
  44.    
  45.         #print("num points: " + str(num_points))
  46.         xs = points[:, 0]
  47.         ys = points[:, 1]
  48.         x_mean = np.average(xs)
  49.         y_mean = np.average(ys)
  50.  
  51.         xy_mean = np.average(xs * ys)
  52.  
  53.         x_squared_mean = np.average(xs ** 2)
  54.    
  55.         if(x_mean ** 2 == x_squared_mean):
  56.             m = sys.float_info.max
  57.         else:
  58.             m = ((x_mean * y_mean) - xy_mean) / ((x_mean ** 2) - x_squared_mean)
  59.        
  60.         b = y_mean - (m * x_mean)
  61.  
  62.         return (m,b)
  63.  
  64.  
  65.     def find_inliers(m, b, shape):
  66.         x1, y1, x2, y2 = None, None, None, None
  67.         found_point_one = False
  68.        
  69.         for x_point in range(0, shape[0]):
  70.             if 0 <= (m*x_point)+b <= shape[1] and not found_point_one:
  71.                 x1 = x_point
  72.                 y1 = (m*x1)+b
  73.                 found_point_one = True
  74.                
  75.             if 0 <= (m*x_point)+b <= shape[1]:
  76.                 x2 = x_point
  77.                 y2 = (m*x2)+b
  78.        
  79.         return x1, x2, y1, y2
  80.  
  81.     def process(self, img):
  82.         """
  83.        Takes in an img param and finds the line in it, if it exists
  84.  
  85.            Args:
  86.                - img : OpenCV Image to process
  87.  
  88.            Publishes:
  89.                - annotated image to the /image_to_cv/processed topic
  90.         """
  91.        
  92.         # Get a colored copy of the image. This will be used solely to provide an annotated version
  93.         # of the image for debuging purposes (for you to see in rqt_image_view). See slides for help here
  94.  
  95.         # Threshold the image to isolate the line and use it for your linear regression algorithm
  96.         # (tip: check size to ensure you are detecting the LED line or a simple blip on the screen)
  97.  
  98.         # "Draw" a line if you have found one on the image
  99.  
  100.         # Publish your newly annotated, color image
  101.         # NOTE: If you do not detect a line, or if you have decided to ignore detected lines of very small
  102.         #       size, be sure to still publish the image. Also be sure to have some way to handle the camera
  103.         #       seeing multiple "lines" at one time
  104.  
  105.         colored_img = img
  106.  
  107.         _, thresh_img = cv2.threshold(img, 245, 255, cv2.THRESH_BINARY)
  108.        
  109.         m, b = calculate_regression(np.argwhere(thresh_img))
  110.        
  111.         x1, x2, y1, y2 = find_inliers(m, b, thresh_img.shape)
  112.        
  113.         cv2.line(colored_img, (x1, y1), (x2, y2), color='lime', thickness = 3)
  114.        
  115.         self.image_pub.publish(colored_img)
  116.  
  117.  
  118. if __name__ == "__main__":
  119.     rospy.init_node("image_to_cv")
  120.     a = ImageToCV()
  121.  
  122.     rospy.spin()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement