Пример #1
0
    def gen_blog_entry(self, roi_id, obj_id, objs):

        print 'Region: ' + self.get_roi_name(roi_id)
        time = dt.fromtimestamp(int(rospy.get_time()))
        body = '### CHANGE DETECTION REPORT\n\n'
        body += '- **Region:** ' + self.get_roi_name(roi_id) + '\n\n'
        #body += '- **Object ID:** ' + str(obj_id)  + '\n\n'
        body += '- **Time:** ' + str(time)  + '\n\n'

        # Create some blog entries
        msg_store = MessageStoreProxy(collection=self.blog_collection)
        robblog_path = roslib.packages.get_pkg_dir('soma_utils') 

        for idx,obj in enumerate(objs):
            
            bridge = CvBridge()
            im = bridge.imgmsg_to_cv2(obj.image_mask, desired_encoding="bgr8")
            imgray = cv2.cvtColor(im,cv2.COLOR_BGR2GRAY)
            ret,thresh = cv2.threshold(imgray,1,1,1) #cv2.threshold(imgray,127,255,0)
            contours, hierarchy = cv2.findContours(thresh,cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE)

            bridge = CvBridge()
            cv_image = bridge.imgmsg_to_cv2(obj.image_full, desired_encoding="bgr8")
            
            cv2.drawContours(cv_image,contours,-1,(0,0,255),2)
            full_scene_contour = bridge.cv2_to_imgmsg(cv_image)
            img_id = msg_store.insert(full_scene_contour)

            body += '<font color="red">Detected change (' + str(idx+1) + '/'+ str(len(objs)) + '):</font>\n\n![My helpful screenshot](ObjectID(%s))\n\n' % img_id
            
        e = RobblogEntry(title=str(time) + " Change Detection - " + self.roi_name[roi_id], body= body )
        msg_store.insert(e)
Пример #2
0
class ROSSubscriber(object):
    def __init__(self, parent, data, loglevel):
        self._parent = parent
        self._data = data
        self.logger = logging.getLogger('ROSSubscriber')
        self.logger.addHandler(CH)
        self.logger.setLevel(loglevel)
        self.hand_sub = mfilters.Subscriber(
            "hand", Image)
        self.skel_sub = mfilters.Subscriber(
            "skeleton", Image)
        self.clas_sub = mfilters.Subscriber(
            "class", TimeReference)
        self.image_ts = mfilters.TimeSynchronizer(
            [self.hand_sub, self.skel_sub,
             self.clas_sub], 30)
        self.image_ts.registerCallback(
            self.callback)
        self.bridge = CvBridge()
    def callback(self, hand, skel, class_name):
        hand = self.bridge.imgmsg_to_cv2(hand,
                                              desired_encoding=
                                              'passthrough')
        skel = self.bridge.imgmsg_to_cv2(skel,
                                              desired_encoding=
                                              'passthrough')
        self._data.add(hand, skel, class_name.source,
                       class_name.time_ref.secs)
        evt = CreateEvent(EVT_ROS_TYPE, -1)
        wx.PostEvent(self._parent, evt)
def run():
  global right_image
  global left_image

  # Init node
  rospy.init_node("stereo_vision");

  # Subscribe for two "eyes"
  rospy.Subscriber("/stereo/right/image_raw", Image, right_image_callback)
  rospy.Subscriber("/stereo/left/image_raw", Image, left_image_callback)

  stereo_publisher = rospy.Publisher("/vision/stereo", Image, queue_size=1000)

  # Action
  print "Start processing..."

  bridge = CvBridge()
  worker = StereoVision()

  # rate = rospy.Rate(10)

  while not rospy.is_shutdown():

    if right_image != None and left_image != None:

      cv_right_image = bridge.imgmsg_to_cv2(right_image, desired_encoding="bgr8")

      cv_left_image = bridge.imgmsg_to_cv2(left_image, desired_encoding="bgr8")

      cv_stereo_image = worker.create_stereo_image( cv_right_image, cv_left_image )

      stereo_image = bridge.cv2_to_imgmsg(cv_stereo_image, encoding="bgr8")

      stereo_publisher.publish( stereo_image )
Пример #4
0
class PatchSaver(object):

    def __init__(self):
        rospy.init_node('patch_saver',log_level=rospy.DEBUG)

        self.patch_array_sub = rospy.Subscriber('patch_array', PatchArray,
                self.patch_array_callback, None, 1)

        self.debug_img_pub = rospy.Publisher('patch_array_debug_img', Image)

        self.bridge = CvBridge()

        self.path = rospy.get_param('~save_path')

    def patch_array_callback(self, PatchArray):
        rospy.loginfo("Patch Array Callback")
        num = np.random.random()
        if ((len(PatchArray.patch_array) > 1) and num > 0.9) or (num > 0.95):
            for idx, patch in enumerate(PatchArray.patch_array):
                image = np.asarray(self.bridge.imgmsg_to_cv2(patch.image,'bgr8'))
                mask = np.asarray(self.bridge.imgmsg_to_cv2(patch.mask,'mono8'))
                cv2.imwrite(self.path +
                        str(int(PatchArray.header.stamp.to_sec() * 1000))
                        + "_" + str(idx) + "_image.png", image)
                cv2.imwrite(self.path +
                        str(int(PatchArray.header.stamp.to_sec() * 1000))
                        + "_" + str(idx) + "_mask.png", mask)
def callback(data):
  global zero, prev

  #cv2.namedWindow("flow",1)
  #cv2.moveWindow("flow",500,00)

  #cv2.namedWindow("zero_image",1)
  #cv2.moveWindow("zero_image",600,0)

  bridge = CvBridge()

  if zero:
    prev = bridge.imgmsg_to_cv2(data, "mono8")
    cv_image = cv2.flip(prev,1)
    #ret1,prev = cv2.threshold(prev, 0, 0,cv2.THRESH_BINARY)
    zero = False
  
  #cv2.imshow("zero_image", prev)
#  cv_image = bridge.imgmsg_to_cv2(data, "bgr8")
  cv_image = bridge.imgmsg_to_cv2(data, "mono8")
  #gray = cv2.cvtColor(cv_image, cv2.COLOR_BGR2GRAY)
  
  cv_image = cv2.flip(cv_image,1)
  #cv2.imshow("motion_detector", cv_image)
  
  motion_detector(cv_image, prev)
Пример #6
0
def callback2(data):
    global face_det
    global filename
    global datei
    #rospy.loginfo(rospy.get_caller_id()+"CDIA data:" + str(len(data.head_detections)))
    if len(data.head_detections)==1 and len(data.head_detections[0].face_detections) == 1:
        face_det+=1
        print face_det
        bridge = CvBridge()
        image = bridge.imgmsg_to_cv2(data.head_detections[0].color_image,"rgb8")
        depth = bridge.imgmsg_to_cv2(data.head_detections[0].depth_image,"32FC3")
        #cv2.imshow("image",image)
        cv2.imshow("depth",depth)
        cv2.waitKey()
        print depth.shape
        set_name = datei[1]
        depth_path="/home/stefan/rgbd_db_heads/"+set_name+"/"+filename+"_d.xml"
        img_path="/home/stefan/rgbd_db_heads/"+set_name+"/"+filename+"_c.bmp"
        #path+"/"+str(dir)+"/"+os.path.splitext(file)[0]+".xml"
        depth_slice1 = depth[:,:,0].astype(numpy.float32)
        depth_slice2 = depth[:,:,1].astype(numpy.float32)
        depth_slice3 = depth[:,:,2].astype(numpy.float32)

        for(r,c),value in numpy.ndenumerate(depth_slice1):
            if depth_slice1[r,c]==0:
                depth_slice1[r,c]=numpy.nan
        for(r,c),value in numpy.ndenumerate(depth_slice2):
            if depth_slice2[r,c]==0:
                depth_slice2[r,c]=numpy.nan
        print filename
Пример #7
0
class ButtonGui(QDialog):
    def __init__(self):
        QDialog.__init__(self)

        self.controller = BasicDroneController()

        uic.loadUi(join(dirname(__file__), 'mav_control.ui'), self)
        self.setWindowTitle('AR.Drone Video Feed')
        self.cv = CvBridge()

        self.trackingColor = np.array([1, 0, 0], dtype=np.float32)


    def videoFrame(self, image):
        self.cv_image = self.cv.imgmsg_to_cv2(image, "rgb8")
        self.cv_image = cv2.cvtColor(self.cv_image, cv2.COLOR_BGR2RGB)
        self.cv_image = cv2.resize(self.cv_image, (self.cv_image.shape[1]/2, self.cv_image.shape[0]/2))
        lab_img, cont_image, center_mass, cont_area = find_car(self.cv_image, self.trackingColor, self.hsThreshold.value()/100.0)
        self.cv_image = find_rectangles(self.cv_image)
        qi = QImage(cont_image.data, cont_image.shape[1], cont_image.shape[0], QImage.Format_RGB888).rgbSwapped()
        self.lbVideo.setFixedHeight(cont_image.shape[0])
        self.lbVideo.setFixedWidth(cont_image.shape[1])
        self.lbVideo.setPixmap(QPixmap.fromImage(qi))
        

        x_center = center_mass[0]
        y_center = center_mass[1]

        self.handle(cont_area)

        if self.cbAuto.isChecked():
            self.fly(x_center, y_center, cont_area)
        else:
            self.lbAuto.setText('Disabled.')

    def handle(self, cont_area):
        self.area = cont_area

    def videoFrame1(self, image):
        self.cv_image = self.cv.imgmsg_to_cv2(image, "rgb8")
        self.cv_image = cv2.cvtColor(self.cv_image, cv2.COLOR_BGR2RGB)
        self.cv_image = cv2.resize(self.cv_image, (self.cv_image.shape[1]/2, self.cv_image.shape[0]/2))
        lab_img, cont_image, center_mass, cont_area = find_car(self.cv_image, self.trackingColor, self.hsThreshold.value()/100.0)
        self.cv_image = find_rectangles(self.cv_image)
        qi = QImage(cont_image.data, cont_image.shape[1], cont_image.shape[0], QImage.Format_RGB888).rgbSwapped()
        self.lbVideo1.setFixedHeight(cont_image.shape[0])
        self.lbVideo1.setFixedWidth(cont_image.shape[1])
        self.lbVideo1.setPixmap(QPixmap.fromImage(qi))

    def fly(self, x_center, y_center, cont_area):
        pass
    
    # On a mouse press, select a tracking color.
    def mousePressEvent(self, QMouseEvent):
        x = QMouseEvent.x() - self.lbVideo.x()
        y = QMouseEvent.y() - self.lbVideo.y()

	if x >= 0 and y >= 0 and x < self.lbVideo.width() and y < self.lbVideo.height():
            self.trackingColor = np.array(self.cv_image[y, x], dtype=np.float32)/255.0
Пример #8
0
class pathfinder:

    cv_image = None
    cv_depth_image = None
    thresh = None

    def __init__(self):
        self.bridge = CvBridge()
        cam_data = rospy.Subscriber("camera_data", CameraData, self.rgb_filter)

    def rgb_filter(self, data):
        cv_image = self.bridge.imgmsg_to_cv2(data.rgb_image)
        cv_image = cv2.flip(cv_image, 0)
        depth_thresh = self.bridge.imgmsg_to_cv2(data.thresh_image)
        #depth_thresh = cv2.resize(depth_thresh, (640,480), interpolation=cv2.INTER_AREA)
        cv_image_mask = cv2.bitwise_and(cv_image, cv_image, mask=depth_thresh)
        grayscale_thresh = self.gray_filter(cv_image_mask)
        ret, contours, hierarchy = cv2.findContours(grayscale_thresh,cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)
        self.cnt = self.contour_filter(contours)
        img = cv2.drawContours(cv_image, self.cnt, -1, (0,255,0), 3)
        cv2.fillPoly(cv_image, pts =[self.cnt], color=(0,255,0))
        cv2.imshow("Image Window", cv_image)
        #cv2.imshow("Grayscale", grayscale_thresh)
        cv2.waitKey(3)

    def hsv_filter(self, cv_image):
        hsv = cv2.cvtColor(cv_image, cv2.COLOR_BGR2HSV)
        mask = np.zeros(cv_image.shape[:2], np.uint8)
        mask[200:500, 200:400] = 255
        masked_img = cv2.bitwise_and(cv_image,cv_image,mask = mask)
        #hist_mask = cv2.calcHist([cv_image],[0],mask,[256],[0,256])
        mean_hsv = cv2.mean(hsv, mask = mask)
        lower_hsv = [self.calc_hsv(mean_hsv[0],1), self.calc_hsv(mean_hsv[1],1), self.calc_hsv(mean_hsv[2],1)]
        upper_hsv = [self.calc_hsv(mean_hsv[0],0), self.calc_hsv(mean_hsv[1],0), self.calc_hsv(mean_hsv[2],0)]
        np_lower_hsv = np.array(lower_hsv, dtype=np.uint8)
        np_upper_hsv = np.array(upper_hsv, dtype=np.uint8)
        thresh = cv2.inRange(hsv, np_lower_hsv, np_upper_hsv)
        return thresh

    def gray_filter(self, cv_image):
        grayscale = cv2.cvtColor(cv_image, cv2.COLOR_BGR2GRAY)
        mask = np.zeros(cv_image.shape[:2], np.uint8)
        mask[300:500, 150:450] = 255
        masked_img = cv2.bitwise_and(cv_image,cv_image,mask = mask)
        mean_gray = cv2.mean(grayscale, mask=mask)
        #cv2.imshow("Mask", mask)
        thresh = cv2.inRange(grayscale, mean_gray[0]-20, mean_gray[0]+20)
        return thresh

    def contour_filter(self, contours):
        return max(contours, key=cv2.contourArea)

    def calc_hsv(self, hsv, over_under):
        if over_under==1:
            return int(hsv-(float(hsv/2.0)))
        else:
            return int(hsv+(float(hsv/2.0)))
Пример #9
0
class cvBridgeDemo():
    def __init__(self):
        self.node_name = "cv_bridge_demo"
        rospy.init_node(self.node_name)
        # What we do during shutdown
        rospy.on_shutdown(self.cleanup)
        # Create the OpenCV display window for the RGB image
        self.bridge = CvBridge()
        self.clock = rospy.Time()
        self.intR = 0000
        # Create a depth generator
        # Subscribe to the camera image and depth topics and set
        # the appropriate callbacks
        self.action = 'stop'
        self.I = []
        self.RGB_sub = message_filters.Subscriber('/camera/rgb/image_rect_color', Image)
        self.Depth_sub = message_filters.Subscriber('/camera/depth_registered/hw_registered/image_rect', Image)
        # rospy.Subscriber('Scene',String,callbackS)
        self.ts = message_filters.ApproximateTimeSynchronizer([self.RGB_sub, self.Depth_sub], 1000,0.02)
        # self.image_sub = rospy.Subscriber("/camera/rgb/image_rect_color", Image, self.image_callback)
        # self.depth_sub = rospy.Subscriber("/camera/depth/image_raw", Image, self.depth_callback)
        self.ts.registerCallback(self.image_callback)
        cv2.namedWindow("RGB",cv2.WINDOW_AUTOSIZE)
        rospy.loginfo("Waiting for image topics...")

    def image_callback(self, ros_image, depth_image):
        try:
            depth_image = self.bridge.imgmsg_to_cv2(depth_image, "passthrough")
            frame = self.bridge.imgmsg_to_cv2(ros_image, "bgr8")
            # d_image = self.bridge.imgmsg_to_cv2(depth_image, "passthrough")
        except CvBridgeError, e:
            print e
        # start_time = timeit.default_timer()  # Convert the image to a Numpy array since most cv2 functions
        # require Numpy arrays.
        frame = np.array(frame, dtype=np.uint8)
        depth_array = np.array(depth_image, dtype=np.float32)
        depth_array = np.nan_to_num(depth_array)
        # gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
        # gray = cv2.equalizeHist(gray)
        # faceCascade = cv2.CascadeClassifier("face_cascada.xml")
        # faces = faceCascade.detectMultiScale(gray, scaleFactor=1.3, minNeighbors=4, minSize=(30, 30),
        #                                      flags=cv2.cv.CV_HAAR_SCALE_IMAGE)
        # print depth_array.shape
        # for (x, y, w, h) in faces:
        #     cv2.rectangle(frame,(x,y),(x+w,y+h),(255,255,0),2)
        #     print depth_array[y+(h/2),x+(w/2)]
        if self.action == 'save':
            print "Saving..."
            self.I.append((frame,depth_array))
        cv2.imshow("RGB",frame)
        key = cv2.waitKey(10) & 0xFF
        if key == ord('s'):
            self.action = 'save'
        elif key == ord('q'):
            self.action = 'stop'
        self.intR += 1
Пример #10
0
class image_converter:

  def __init__(self):
    rospy.init_node('image_converter', anonymous=True)
    self.bridge = CvBridge()
    self.image_sub = rospy.Subscriber("/stereo/left/image_raw",Image,self.callback_left)
    self.image_sub = rospy.Subscriber("/stereo/right/image_raw",Image,self.callback_right)
    self.left=[]
    self.right=[]

  def cropcrop(self,frame):
            par = Parameters
            matrix = create_distortion_matrix(
                par.fxL, par.cxL, par.fyL, par.cyL
            )
            frame = translate(frame, par.xL + par.xo, par.yL + par.yo)
            frame = transform(frame, matrix)
            frame = translate(frame, par.xo2, par.yo2)

            frame = crop(
                frame,
                par.cropXL,
                par.cropXR,
                par.cropYL,
                par.cropYR,
            )

	    return frame

  def callback_left(self,data):
    cv_image = self.bridge.imgmsg_to_cv2(data, "bgr8")
    self.left=cv_image

  def callback_right(self,data):
    cv_image = self.bridge.imgmsg_to_cv2(data, "bgr8")
    self.right=cv_image

  def virtualize(self):
    rate = rospy.Rate(30) # 10hz
    while not rospy.is_shutdown():
	if (self.left!=[] and self.right!=[]):
	    left_frame=self.cropcrop(cv2.flip(self.left,1))
	    right_frame=self.cropcrop(cv2.flip(self.right,1))

	    #put two images together
	    composite_frame = join_images(
		        right_frame,
                        left_frame,
	    )
            composite_frame=cv2.transpose(composite_frame)
            cv2.namedWindow("test", cv2.WND_PROP_FULLSCREEN)
            cv2.setWindowProperty("test", cv2.WND_PROP_FULLSCREEN, cv2.cv.CV_WINDOW_FULLSCREEN)
            cv2.imshow("test",composite_frame)
    	    cv2.waitKey(3)
        rate.sleep()
    def cb(self, ubd, rgb, d):
        b = CvBridge()
        rgb = b.imgmsg_to_cv2(rgb)[:,:,::-1]  # Need to do BGR-RGB conversion manually.
        d = b.imgmsg_to_cv2(d)

        for i, detrect in enumerate(zip(ubd.pos_x, ubd.pos_y, ubd.width, ubd.height)):
            cv2.imwrite(pjoin(self.dirname, "{:06d}.png".format(self.counter)), cutout(rgb, detrect, self.hfact))
            det_d = cutout(d, detrect, self.hfact)

            stderr.write("\r{}".format(self.counter)) ; stderr.flush()
            self.counter += 1
Пример #12
0
class cvBridgeDemo():
    def __init__(self,path_base,path):
        self.node_name = "cv_bridge_demo"
        rospy.init_node(self.node_name)
        self.path_base = path_base+"/"+path
        if not os.path.exists(self.path_base+"/RGB"):
            os.makedirs(self.path_base+"/RGB")
        if not os.path.exists(self.path_base + "/Depth"):
            os.makedirs(self.path_base + "/Depth")
        # What we do during shutdown
        rospy.on_shutdown(self.cleanup)
        # Create the OpenCV display window for the RGB image
        self.bridge = CvBridge()
        self.label='None'
        self.clock = rospy.Time()
        self.init = int(0)
        self.end = int(10000000)
        self.intR = 0000
        self.file = open(self.path_base+"/List.txt",'w')
        # Create a depth generator
        # Subscribe to the camera image and depth topics and set
        # the appropriate callbacks
        self.RGB_sub = message_filters.Subscriber('/camera/rgb/image_rect_color', Image)
        self.Depth_sub = message_filters.Subscriber('/camera/depth_registered/hw_registered/image_rect', Image)
        self.ts = message_filters.ApproximateTimeSynchronizer([self.RGB_sub, self.Depth_sub], 1000,0.02)
        self.ts.registerCallback(self.image_callback)
        rospy.loginfo("Waiting for image topics...")


    def image_callback(self, ros_image, depth_image):
        # Use cv_bridge() to convert the ROS image to OpenCV format
        try:
            frame = self.bridge.imgmsg_to_cv2(ros_image, "bgr8")
            depth = self.bridge.imgmsg_to_cv2(depth_image, "passthrough")
            # d_image = self.bridge.imgmsg_to_cv2(depth_image, "passthrough")
        except CvBridgeError, e:
            print e
        depth_array = np.array(depth, dtype=np.float32)
        depth_array = np.nan_to_num(depth_array)
        self.clock = rospy.get_time()
        # Convert the image to a Numpy array since most cv2 functions
        # require Numpy arrays.
        cv2.imwrite(self.path_base + "/RGB" + "/Frame_" + self.intR.__str__() + "_RGB.jpg", frame)
        np.save(self.path_base + "/Depth" + "/Frame_" + self.intR.__str__() + "_Depth.npy", depth_array)
        self.file.write(self.clock.__str__() + "\n" +
                        "Frame_" + self.intR.__str__() + "_RGB.jpg" + "\n" +
                        "Frame_" + self.intR.__str__() + "_Depth.png\n" + self.label + "\n")
        self.intR += 1
class Echo:
    def __init__(self):
        self.node_name = "BlobDetector"
        self.thread_lock = threading.Lock()
        self.sub_image = rospy.Subscriber("/camera/rgb/image_rect_color",\
                Image, self.cbImage, queue_size=1)
        self.pub_image = rospy.Publisher("/blob_image",\
                Image, queue_size=1)
        self.pub_data = rospy.Publisher("/blob_detections", BlobDetections, queue_size = 1)
        self.bridge = CvBridge()

        rospy.loginfo("[%s] Initialized." %(self.node_name))

    def cbImage(self,image_msg):
        thread = threading.Thread(target=self.processImage,args=(image_msg,))
        thread.setDaemon(True)
        thread.start()


    def processImage(self, image_msg):
        if not self.thread_lock.acquire(False):
            return
        image_cv = self.bridge.imgmsg_to_cv2(image_msg)
        msg, img = process(image_cv) 
        try:
            self.pub_image.publish(self.bridge.cv2_to_imgmsg(img, "bgr8"))
            self.pub_data.publish(msg)
        except CvBridgeError as e:
            print(e)
        self.thread_lock.release()
Пример #14
0
class image_subscriber:
    def __init__(self, object_name):
	self.object_name = object_name
	self.bridge = CvBridge()
        self.rospack = rospkg.RosPack()        
        #rospy.wait_for_service('getImage')
        #self.getImage_client = rospy.ServiceProxy('image_preparator/getImage', getImage)
        #self.UpdateTFs_client = rospy.ServiceProxy('image_preparator/UpdateTFs', UpdateTFs)
        self.SaveCloud_client = rospy.ServiceProxy('cloud_saver/SaveCloud', SaveCloud)
        
	prefix = self.rospack.get_path('deep_cnn_object_detection')
	dir_path = prefix + '/data/images/' + self.object_name
	if not os.path.exists(dir_path):
	    os.makedirs(dir_path)
	pass

    def get_image(self):
	res = self.getImage_client()
	data = res.msg
        try:
            self.image = self.bridge.imgmsg_to_cv2(data, "bgr8")  # bgr or rgb it is no matter, it will be in bgr in both cases
        except CvBridgeError as e:
            print e  
    def save_image(self, image_num):
	prefix = self.rospack.get_path('deep_cnn_object_detection')
	image_path = prefix + '/data/images/' + self.object_name + '/' + str(image_num) + '.jpg'
	cv2.imwrite(image_path, self.image)
	pass
    def save_cloud(self, angle):
	self.SaveCloud_client(angle);
	pass
Пример #15
0
class image_converter:

    def __init__(self):

        cv2.namedWindow("detected circles", 1)
        cv2.startWindowThread()
        self.bridge = CvBridge()
        self.image_sub = rospy.Subscriber("/turtlebot_2/camera/rgb/image_raw",
                                          Image, self.callback)
                                          
    def callback(self, data):

        cv_image = self.bridge.imgmsg_to_cv2(data, "bgr8")

        img = cvtColor(cv_image, COLOR_BGR2GRAY)


        img = cv2.medianBlur(img,5)

        circles = cv2.HoughCircles(img,cv.CV_HOUGH_GRADIENT,4,20,
                                   param1=230,param2=230,minRadius=0,maxRadius=0)
        if circles is not None:
            print len(circles)
            circles = np.uint16(np.around(circles))
            for i in circles[0,:]:
                # draw the outer circle
                cv2.circle(cv_image,(i[0],i[1]),i[2],(0,255,0),2)
                # draw the center of the circle
                cv2.circle(cv_image,(i[0],i[1]),2,(0,0,255),3)
                
            cv2.imshow('detected circles',cv_image)
Пример #16
0
class ImageGUI(object):
    def __init__(self, filename, image_topic):
        rospy.init_node('record_user_input')
        
        # initialize display
        self.window_name = 'user_input'
        cv2.namedWindow(self.window_name,1)
        self.subImage = rospy.Subscriber(image_topic, Image, self.image_callback, queue_size=5, tcp_nodelay=True)
        self.cvbridge = CvBridge()
        
        # initialize file
        self.csvfile = open(filename, 'wb')
        self.datawrite = csv.writer(self.csvfile, delimiter=',', quotechar='|', quoting=csv.QUOTE_MINIMAL)

        # user input
        cv2.setMouseCallback(self.window_name, self.on_mouse_click)
        self.mouse_position = [0,0]

    def image_callback(self, rosimg):
        # Convert the image.
        try:
            img = self.cvbridge.imgmsg_to_cv2(rosimg, 'passthrough') # might need to change to bgr for color cameras
        except CvBridgeError, e:
            rospy.logwarn ('Exception converting background image from ROS to opencv:  %s' % e)
            img = np.zeros((320,240))
        cv2.imshow(self.window_name, img)
        ascii_key = cv2.waitKey(1)
        if ascii_key != -1:
            self.on_key_press(ascii_key)
def shapeCallback(req):
	rosimg = req.im;
	cvbridge = CvBridge()
	try:
		bw_img = cvbridge.imgmsg_to_cv2(rosimg, desired_encoding="passthrough")
	except CvBridgeError, e:
		print e
Пример #18
0
class ImageScale:

    def __init__(self, width=160, height=120):
        self.width = width
        self.height = height
        self.nPrints = 1
        self.bridge = CvBridge()
        rospy.init_node('camera_scaled', anonymous=True)
        rospy.Subscriber('camera/rgb/image_color', Image, self.cameraCallback, queue_size=1)
        self.image_pub = rospy.Publisher("turtle_env/camera_scaled", Image)

        rospy.spin()

    def cameraCallback(self, data):
        if self.nPrints > 0:
            print 'getting callback'
            self.nPrints -= 1

        try:
            cv_image = self.bridge.imgmsg_to_cv2(data, 'rgb8')
        except CvBridge, e:
            print e

        cv_image = cv2.resize(cv_image, (self.width, self.height))
        try:
            self.image_pub.publish(self.bridge.cv2_to_imgmsg(cv_image, "rgb8"))
        except CvBridgeError, e:
            print e
Пример #19
0
class image_converter:

  def __init__(self):
    self.image_pub = rospy.Publisher("image_topic_2",Image)

    cv2.namedWindow("Image window", 1)
    self.bridge = CvBridge()
    self.image_sub = rospy.Subscriber("ardrone/image_raw",Image,self.callback)

  def callback(self,data):
    try:
      cv_image = self.bridge.imgmsg_to_cv2(data, "bgr8")
    except CvBridgeError, e:
      print e

    #(rows,cols,channels) = cv_image.shape
    #if cols > 60 and rows > 60 :
    #  cv2.circle(cv_image, (50,50), 10, 255)

    #cv2.imshow("Image window", cv_image)
    #cv2.waitKey(3)

    try:
      self.image_pub.publish(self.bridge.cv2_to_imgmsg(cv_image, "bgr8"))
    except CvBridgeError, e:
      print e
Пример #20
0
class motion_images :
  history = None
  nframes = 100
  frame = 1
  refPt=[]
  windowhist=[]
  comparehist=[]
  dist=[]
  path=[]
  firstframe= None
  i=0
  index=0
  

  def distance(self, p0, p1): 
    return math.sqrt((p0[0] - p1[0])**2 + (p0[1] - p1[1])**2)


  def __init__(self, source1,source2,sink) :
    self.image_pub = rospy.Publisher(sink, Image, queue_size=25)

    self.bridge = CvBridge()
    self.image_sub1 = rospy.Subscriber(source1, Image, self.callback1)
    self.image_sub2 = rospy.Subscriber(source2, Image, self.callback2) 
   

  def callback1(self, data1) :
    global cv_image1, cv_image2
    try :
      cv_image1 = self.bridge.imgmsg_to_cv2(data1, "bgr8")
    except CvBridgeError, e:
      print e

    (rows,cols,channels) = cv_im
Пример #21
0
class face_position_publisher:
    def __init__(self):
        self.image_pub = rospy.Publisher("face_position", Point, queue_size=10)
        self.bridge = CvBridge()
        self.image_sub = rospy.Subscriber("camera_node/image_raw",Image, self.callback, queue_size=10)
        self.shutter_sub = rospy.Subscriber("/close_eye", Empty,self.save_callback, queue_size=10)
        self.pub = rospy.Publisher('face/position', Point, queue_size=10)
        self.image_publisher = rospy.Publisher('face/recognized', Image, queue_size=10)
        self.cv_image = None
        self.cnt = 0
    def callback(self, data):
        try:
            self.cv_image = self.bridge.imgmsg_to_cv2(data, "bgr8")
            image_gray = cv2.cvtColor(self.cv_image, cv2.cv.CV_BGR2GRAY)
            cascade = cv2.CascadeClassifier(cascade_path)
            facerect = cascade.detectMultiScale(image_gray, scaleFactor=1.1, minNeighbors=10, minSize=(100, 100))
            if len(facerect) > 0:
                for rect in facerect:
                    cv2.rectangle(self.cv_image, tuple(rect[0:2]),tuple(rect[0:2]+rect[2:4]), color, thickness=2)
                    rospy.loginfo(rect)
                    self.pub.publish(Point(x=rect[0:1]+rect[1:2]/2,
                                           y=rect[2:3]+rect[3:]/2,
                                           z=0))
            # self.image_publisher.publish(self.bridge.cv2_to_imgmsg(cv_image, 'bgr8'))
        except CvBridgeError, e:
            print(e)
Пример #22
0
def processFrame(image):

    global pub1, pub2
    conVerter = CvBridge()

    #Convert from a ROS image to a CV image
    try:
        image = conVerter.imgmsg_to_cv2(image, "bgr8")
    except CvBridgeError as e:
        print (e)

    result = bT.computeSpheres(image)
    msgBallCoords = ballcoords()
    msgModImage = Image()
    if result == None:
        return
    msgBallCoords.color= "RED"
    msgBallCoords.x = result[0]
    msgBallCoords.y = result[1]
    msgBallCoords.radius = result[2]

    # convert from a CV image to a ROS image

    resImage = result[3]

    #resImage = conVerter.cv2_to_imgmsg(resImage , "bgr8")
    msgModImage = conVerter.cv2_to_imgmsg(resImage , "bgr8")

    rospy.loginfo(msgBallCoords)
    pub1.publish(msgBallCoords)
    pub2.publish(msgModImage)
Пример #23
0
class image_converter:

	def __init__(self):
		#self.image_pub = rospy.Publisher("image_topic_2",Image)
		cv2.namedWindow("Image window", 1)
		self.bridge = CvBridge()
		self.image_sub = rospy.Subscriber("/camera/rgb/image_raw",Image,self.callback)

	def callback(self,data):
		try:
			cv_image = self.bridge.imgmsg_to_cv2(data, "bgr8")
		except CvBridgeError, e:
			print e

		(rows,cols,channels) = cv_image.shape
                #print rows, cols
		
		rec_points=[(213,0), (213,480),(0,160),(640,160),(0,320),(640,320),(426,0),(426,480)]
                i=0
                while(i<len(rec_points)):
                        p1=rec_points[i]
                        p2=rec_points[i+1]
                        cv2.line(cv_image, p1, p2, (0,255,0), 1, 8, 0)
                        i=i+2
                 
		cv2.imshow("Image window", cv_image)
		cv2.waitKey(3)
Пример #24
0
class smileDetect:
    
    def __init__(self):
        #pdb.set_trace()
        self.image = None
        self.image_pub = rospy.Publisher("image_topic_2",Image)
        self.bridge = CvBridge() 
        self.camera_listener = rospy.Subscriber("camera/image_raw",Image, self.convertingNumpy)
        print "initialized"



    def convertingNumpy(self, msg):
        print "converting image"
        #reads in the images from the camera and converts it from ros image to openCV image
        try:
            cv_image = self.bridge.imgmsg_to_cv2(msg, "bgr8")
        except CvBridgeError, e:
            print e
        self.image = numpy.asanyarray(cv_image)
        print "self.image has length %s" %len(self.image)
        #run facial detection algorithm
        self.detectFaces()
        cv2.imshow ("cv_image", self.image)
        #need this to be in the same method and in the same indent as the cv2.imshow line
        if cv2.waitKey(1) & 0xFF == ord('q'):
            pass
Пример #25
0
class ROSInput(object):
    """
    Capture video via ROS topic
    """
    def __init__(self, input):
        self._image = None
        self._bridge = CvBridge()
        rospy.Subscriber(input, Image, self.imageCallback)

    def imageCallback(self, data):
        try:
            image_raw = self._bridge.imgmsg_to_cv2(data, "bgr8")
        except CvBridgeError as e:
            print(e)
        self._image = image_raw

    def isActive(self):
        return True

    @property
    def image(self):
        return self._image

    def cleanup(self):
        pass

    def isEnabled(self):
        return self._enabled
 def get_img(self, bag):
     bridge = CvBridge()
     for topic, msg, t in bag.read_messages(topics=['/cv_camera/image_raw/']):
         img = bridge.imgmsg_to_cv2(msg, "bgr8")
         rects = self.getCircles(img, 35)
         for rect in rects:
             yield rect
Пример #27
0
	def on_enter(self,userdata):
		bridge =  CvBridge()
		cv_image = bridge.imgmsg_to_cv2(userdata.Image, desired_encoding="passthrough")
		self._filename = os.path.expanduser('~/picture_'+str(rospy.Time.now())+'.jpg')
		print 'Saving file to ' , self._filename
		cv2.imwrite(self._filename,cv_image)
		print 'Picture has been saved to the home folder'   
Пример #28
0
class RosTensorFlow():
    def __init__(self):
        classify_image.maybe_download_and_extract()
        self._session = tf.Session()
        classify_image.create_graph()
        self._cv_bridge = CvBridge()

        self._sub = rospy.Subscriber('image', Image, self.callback, queue_size=1)
        self._pub = rospy.Publisher('result', String, queue_size=1)
        self.score_threshold = rospy.get_param('~score_threshold', 0.1)
        self.use_top_k = rospy.get_param('~use_top_k', 5)

    def callback(self, image_msg):
        cv_image = self._cv_bridge.imgmsg_to_cv2(image_msg, "bgr8")
        # copy from
        # classify_image.py
        image_data = cv2.imencode('.jpg', cv_image)[1].tostring()
        # Creates graph from saved GraphDef.
        softmax_tensor = self._session.graph.get_tensor_by_name('softmax:0')
        predictions = self._session.run(
            softmax_tensor, {'DecodeJpeg/contents:0': image_data})
        predictions = np.squeeze(predictions)
        # Creates node ID --> English string lookup.
        node_lookup = classify_image.NodeLookup()
        top_k = predictions.argsort()[-self.use_top_k:][::-1]
        for node_id in top_k:
            human_string = node_lookup.id_to_string(node_id)
            score = predictions[node_id]
            if score > self.score_threshold:
                rospy.loginfo('%s (score = %.5f)' % (human_string, score))
                self._pub.publish(human_string)

    def main(self):
        rospy.spin()
Пример #29
0
class image_converter:
  def __init__(self):
    rospy.init_node('image_converter', anonymous=True)
    self.image_pub = rospy.Publisher("analyzed_image", Image, queue_size=10)

    self.bridge = CvBridge()
    self.image_sub = rospy.Subscriber("image_raw", Image, self.callback)

    self.stabilizer = VideoStabilizer([[409, 250], [300, 762], [1123, 848], [1600, 238]])


  def callback(self, data):
    try:
      cv_image = self.bridge.imgmsg_to_cv2(data, "bgr8")
    except CvBridgeError as e:
      print(e)

    #cv_image = self.analyze_image(cv_image)
    #self.showImage(cv_image)

    try:
      self.image_pub.publish(self.bridge.cv2_to_imgmsg(cv_image, "bgr8"))
    except CvBridgeError as e:
      print(e)


  def analyze_image(self, image):
    image = self.stabilizer.stabilize_frame(image)
    return image


  def showImage(self, image):
    cv2.imshow("Image window", image)
    cv2.waitKey(3)
Пример #30
0
class BallTracker(object):
    """ The BallTracker is a Python object that encompasses a ROS node 
        that can process images from the camera and search for a ball within.
        The node will issue motor commands to move forward while keeping
        the ball in the center of the camera's field of view. """

    def __init__(self, image_topic):
        """ Initialize the ball tracker """
        rospy.init_node('ball_tracker')
        self.cv_image = None                        # the latest image from the camera
        self.bridge = CvBridge()                    # used to convert ROS messages to OpenCV

        rospy.Subscriber(image_topic, Image, self.process_image)
        self.pub = rospy.Publisher('cmd_vel', Twist, queue_size=10)
        cv2.namedWindow('video_window')

    def process_image(self, msg):
        """ Process image messages from ROS and stash them in an attribute
            called cv_image for subsequent processing """
        self.cv_image = self.bridge.imgmsg_to_cv2(msg, desired_encoding="bgr8")
        print self.cv_image.shape
        cv2.imshow('video_window', self.cv_image)
        cv2.waitKey(5)

    def run(self):
        """ The main run loop, in this node it doesn't do anything """
        r = rospy.Rate(5)
        while not rospy.is_shutdown():
        	# start out not issuing any motor commands
            r.sleep()
class LineDetector:
    def __init__(self, topic):

        self.bridge = CvBridge()
        self.cv_image = np.empty(shape=[0])
        self.value_threshold = 180
        self.image_width = 640
        self.image_middle = 320
        self.scan_height = 40
        self.area_width, area_height = 20, 10
        self.roi_vertical_pos = 300
        self.row_begin = (self.scan_height - area_height) // 2
        self.row_end = self.row_begin + area_height
        self.pixel_cnt_threshold = 0.3 * self.area_width * area_height
        self.detect_node = rospy.Subscriber(topic, Image, self.conv_image)
        self.last_l, self.last_r = 0, 0

    def conv_image(self, data):

        cv_image = self.bridge.imgmsg_to_cv2(data, "bgr8")
        frame = cv_image[self.roi_vertical_pos:self.roi_vertical_pos +
                         self.scan_height, :]
        dst = cv2.Canny(frame, 50, 100)
        cdst = cv2.cvtColor(dst, cv2.COLOR_GRAY2BGR)

        lines = cv2.HoughLinesP(dst, 1, np.pi / 180, 50, None, 50, 5)

        if lines is not None:
            for i in range(0, len(lines)):
                l = lines[i][0]
                cv2.line(cdst, (l[0], l[1]), (l[2], l[3]), (0, 0, 255), 5,
                         cv2.LINE_AA)

        lbound = np.array([0, 0, self.value_threshold], dtype=np.uint8)
        ubound = np.array([131, 255, 255], dtype=np.uint8)

        hsv = cv2.cvtColor(cdst, cv2.COLOR_BGR2HSV)
        self.bin = cv2.inRange(hsv, lbound, ubound)
        self.view = cv2.cvtColor(self.bin, cv2.COLOR_GRAY2BGR)

    def detect_lines(self):
        left, right = -1, -1

        for l in range(self.image_middle, self.area_width, -1):
            area = self.bin[self.row_begin:self.row_end, l - self.area_width:l]
            if cv2.countNonZero(area) > self.pixel_cnt_threshold:
                left = l
                break

        for r in range(self.image_middle, self.image_width - self.area_width):
            area = self.bin[self.row_begin:self.row_end, r:r + self.area_width]
            if cv2.countNonZero(area) > self.pixel_cnt_threshold:
                right = r
                break
        if right > 0 and left > 0 and abs(right - left) < 450:

            if self.last_r == -1:
                right = -1
            elif self.last_l == -1:
                left = -1

            self.last_l = left
            self.last_r = right

        return left, right

    def show_images(self, left, right):

        if left != -1:
            self.lsquare = cv2.rectangle(
                self.view, (left, self.row_begin),
                (left - self.area_width, self.row_end), (255, 255, 0), 3)
        # else:
        # print("")#Lost left line

        if right != -1:
            self.rsquare = cv2.rectangle(
                self.view, (right, self.row_begin),
                (right + self.area_width, self.row_end), (0, 255, 255), 3)
        # else:
        # print("")#Lost right line

        cv2.imshow('view', self.view)
        # print(right, left)
        cv2.waitKey(1)
Пример #32
0
class DemoNode(object):
    def __init__(self):
        self._cv_br = CvBridge()

        self._ros_init()

        self._roi_lock = Lock()
        self._latest_rois = []

        self._depth_lock = Lock()
        self._latest_depth = None

    def _ros_init(self):
        rospy.init_node('debug')

        rospy.Subscriber('/detector/detections', ClassifiedRegionsOfInterest, self._detect_callback, queue_size=1)
        rospy.Subscriber(rospy.get_param('image_topic', '/camera/color/image_raw'), Image, self._camera_callback, queue_size=2)
        rospy.Subscriber(rospy.get_param('depth_topic', '/camera/depth/image_rect_raw'), Image, self._depth_callback, queue_size=2)
        self._publisher = rospy.Publisher('demo', Image, queue_size=2)

    def _detect_callback(self, regions):

        with self._roi_lock:
            self._latest_rois = regions.regions

    def _depth_callback(self, depth):
        with self._depth_lock:
            self._latest_depth = self._cv_br.imgmsg_to_cv2(depth)

    def _camera_callback(self, image):

        frame = self._cv_br.imgmsg_to_cv2(image)

        rois = []
        with self._roi_lock:
            rois = self._latest_rois

        depth = None
        with self._depth_lock:
            depth = self._latest_depth

        for roi in rois:
            cv2.rectangle(frame, (roi.x, roi.y),
                          (roi.x + roi.w, roi.y + roi.h), (0, 255, 0), 10)

            if depth is not None:
                y_scale = depth.shape[0] / frame.shape[0]
                x_scale = depth.shape[1] / frame.shape[1]

                d_x = int(roi.x * x_scale)
                d_y = int(roi.y * y_scale)
                d_w = int(roi.w * x_scale)
                d_h = int(roi.h * y_scale)

                sub_depth = depth[d_y:d_y+d_h,d_x:d_x+d_w]

                median_distance = np.median(sub_depth) / 1000.0

                cv2.putText(frame, "%.1f m" % median_distance, (max(0, roi.x), max(0, roi.y - 20)), cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 255, 0), 2, cv2.LINE_AA)

        self._publisher.publish(self._cv_br.cv2_to_imgmsg(cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)))
Пример #33
0
class ObjectTracking(object):
    def __init__(self, SPR_opt, init_estimate):
        self.SPR_opt = SPR_opt
        self.init_estimate = init_estimate
        self.estimate = init_estimate
        self.target = init_estimate
        self.pub = rospy.Publisher('/spr/dlo_estimation', PointCloud, queue_size=3)
        # object that listen to transformation tree. 
        self.tf_listener = tf.TransformListener()
        self.target_num_points = 300
        self.min_num_points = self.target_num_points/3
        self.voxel_size = 15
        self.offset_xyz = np.array([-0.045,0,0]) # offset in x,y,z in meters
        # camera properites
        self.camera_properties = {
            'res_color_height': 720,
            'res_color_width': 1280,
            'res_depth_height': 480,
            'res_depth_width': 640,
            'color_K': np.array([[919.5044555664062, 0.0, 645.03076171875,],\
                [0.0, 919.5109252929688, 357.19921875],[0.0, 0.0, 1.0]]),
            'depth_K': np.array([[385.37188720703125, 0.0, 320.0655517578125],\
            [0.0, 385.37188720703125, 241.86325073242188],[0.0, 0.0, 1.0]]),
            'depth_reshape': np.array([[1],[640]])
        }
        # from ros image to opencv image
        self.bridge = CvBridge()
        self.pcd = o3d.geometry.PointCloud() #creating point cloud

        # set to something else if apriltags are not used and manual calibration is desierd. 
        self.tag_quaternion_xyzw = np.zeros(4)
        self.tag_translation_xyz = np.zeros(3)
        self.rotation_matrix = np.eye(3)
        self.num_calibration_itter = 0

        # filter table
        self.height_off = -0.004 # m offest for which all points under get filtered away

    def callback(self, depth_data, rgb_data):
        time_start = time.time()

        try:
            color_img = self.bridge.imgmsg_to_cv2(rgb_data, rgb_data.encoding)
        except CvBridgeError as e:
            print(e)
        
        self.stamp = rgb_data.header.stamp
        self.frame_id = rgb_data.header.frame_id
        # keep the 16 bit information 
        depth_vec = np.frombuffer(depth_data.data, dtype=np.uint16)

        depth_img = depth_vec.reshape((self.camera_properties['res_depth_height'], \
             self.camera_properties['res_depth_width']))
        
        depth_img = depth_img/1000 # from milimeter int to float meter. 

        # mask cable
        black_lower = (0, 0, 0)
        black_upper = (180, 255, 25)

        blue_lower = (100, 235, 50)
        blue_upper = (120, 255, 255)

        hsv_image = cv2.cvtColor(color_img, cv2.COLOR_RGB2HSV)
        mask = cv2.inRange(hsv_image, blue_lower, blue_upper)
      
        # get coord
        [row,col]=np.nonzero(mask)

        p_color = np.transpose(np.array([col, row, np.ones(np.size(row))]))

        # down sample
        self.pcd.points = o3d.utility.Vector3dVector(p_color)
        self.pcd = self.pcd.voxel_down_sample(voxel_size=self.voxel_size)

        #homogeneous coordinates 
        K_inv = np.linalg.pinv(self.camera_properties['color_K'])
        p_homogeneous = np.transpose(K_inv.dot(np.asarray(self.pcd.points).T))
        p_homogeneous_offset = p_homogeneous# + self.offset_xyz

        #cv2.namedWindow('RealSense', cv2.WINDOW_AUTOSIZE)
        #cv2.imshow('RealSense', depth_img)
        #cv2.imshow('RealSense', mask)
        #cv2.waitKey(1)


        if np.shape(p_homogeneous)[0] > self.min_num_points: 
            # dynamic downsample
            down_samlpe = np.shape(p_homogeneous)[0] / self.target_num_points
            if down_samlpe < 0.95:
                self.voxel_size -= 0.2    
            elif down_samlpe > 1.05:
                self.voxel_size += 0.2    
        
            # to depth camera 
            p_depth = np.transpose(self.camera_properties['depth_K'].dot(p_homogeneous_offset.T)) 

            # round to nearest int
            p_depth_idx = np.rint(p_depth)
            indices = p_depth_idx[:,0:2].astype(int).dot(self.camera_properties['depth_reshape'])
            
            # clip indecies within range, maybe implement a better version in future
            indices = indices.clip(0, \
                (self.camera_properties['res_depth_height']*self.camera_properties['res_depth_width']-1))
            depth_z = depth_img.reshape(-1)[indices]

            # calculate point cloud            
            point_cloud = p_homogeneous*depth_z

            # remove non vaild points
            point_cloud = point_cloud[~np.all(point_cloud == 0, axis=1)]
            
            # get transformation matrix
            (trans, rot) = self.tf_listener.lookupTransform('/yumi_base_link', '/camera_color_optical_frame', rospy.Time(0))
            transformer_ = tf.TransformerROS(True, rospy.Duration(1.0))
            tf_matrix = transformer_.fromTranslationRotation(translation=trans, rotation=rot)

            # homogenious coordinates 
            col_ones = np.ones((np.shape(point_cloud)[0],1))
            point_cloud = np.hstack((point_cloud,col_ones))

            # Transform
            point_cloud = np.transpose(tf_matrix.dot(point_cloud.T))
            
            # flattend 
            point_cloud = point_cloud[:,0:3]/point_cloud[:,3:4]

            # remove point that are under certatin hight from the worktable 
            index_ = point_cloud[:,2] >= self.height_off
            point_cloud = point_cloud[index_,:]

            self.target = point_cloud

            # plot depthimage and slected points for calibration 
            #depth_img.reshape(-1)[indices] = 255
            #cv2.namedWindow('RealSense', cv2.WINDOW_AUTOSIZE)
            #cv2.imshow('RealSense', depth_img)
            #cv2.imshow('RealSense', mask)
            #cv2.waitKey(1)
            
            # call SPR 
            SPR_Transform = spr_local.SPR_register(self.target, self.estimate, self.SPR_opt)  # CPD warp Y to X, fliped! X_warp = SPR_Transform.Y;
            self.estimate = SPR_Transform.get('Y')
            time_update = time.time() - time_start 
            print('time_update ', time_update)
            self.publish_msg()

    def publish_msg(self):
        cloudpoints = self.estimate
        cloud_msg = PointCloud()
        cloud_msg.header.stamp = self.stamp
        cloud_msg.header.frame_id = "yumi_base_link"

        for i in range(cloudpoints.shape[0]):
            cloud_msg.points.append(Point32(cloudpoints[i, 0], cloudpoints[i, 1], cloudpoints[i, 2])) 
            # Change to camera frame
        self.pub.publish(cloud_msg)

    def update_transformation(self):
        pass

    def update_calibration_color(self, camera_info): 
        K = np.array(camera_info.K)
        self.camera_properties['color_K'] = K.reshape((3, 3))
        self.camera_properties['res_color_width'] = camera_info.width
        self.camera_properties['res_color_height'] = camera_info.height


    def update_calibration_depth(self, camera_info):
        K = np.array(camera_info.K)
        self.camera_properties['depth_K'] = K.reshape((3, 3))
        self.camera_properties['res_depth_width'] = camera_info.width
        self.camera_properties['res_depth_height'] = camera_info.height
        self.camera_properties['depth_reshape'] = np.array([[1],[camera_info.width]])
Пример #34
0
class image_handler:

    # Constructor
    def __init__(self):
        self.pub_det = rospy.Publisher("image/detection", Image)

        self.bridge = CvBridge()
        self.image_sub = rospy.Subscriber("/camera/image_raw", Image,
                                          self.callback)

        self.curr_kp = None
        self.curr_desc = None
        self.train_kp = None
        self.train_desc = None
        self.detect = False
        self.img_train = None

        self.referencePoints = []
        self.cropping = False

    # Callback
    def callback(self, data):

        # recibimos una nueva imagen como 'data' y la convertimos en imagen de opencv
        try:
            self.cv_image = self.bridge.imgmsg_to_cv2(data, "bgr8")
        except CvBridgeError as e:
            print(e)

        # obtener dimensiones de la imagen
        (rows, cols, channels) = self.cv_image.shape

        # pasar a escala de grises
        gray = cv2.cvtColor(self.cv_image, cv2.COLOR_BGR2GRAY)

        #-------------------------------------------------------
        # Feature Detector and Description

        self.detector = cv2.xfeatures2d.SIFT_create()
        #self.detector = cv2.xfeatures2d.SURF_create()
        #self.detector = cv2.KAZE_create()
        #self.detector = cv2.AKAZE_create()
        #self.detector = cv2.BRISK_create()
        #self.detector = cv2.ORB_create()

        (self.curr_kp,
         self.curr_desc) = self.detector.detectAndCompute(gray, None)

        img_kp = cv2.drawKeypoints(self.cv_image,
                                   self.curr_kp,
                                   None,
                                   color=(0, 0, 255))

        cv2.imshow('image', img_kp)
        cv2.setMouseCallback('image', self.clipAndCrop)

        # eventos de teclado
        k = cv2.waitKey(30)

        #-------------------------------------------------------
        # Image matching

        if self.detect:
            # creamos objeto que realiza matching de fuerza bruta (Brute Force Matching, BFMatcher)
            # OJO: cuidado con el tipo de descriptor (binario o punto flotante)
            #bf = cv2.BFMatcher(cv2.NORM_HAMMING, crossCheck=True)
            bf = cv2.BFMatcher(cv2.NORM_L2, crossCheck=True)

            # Matching de descriptores
            matches = bf.match(self.train_desc, self.curr_desc)

            # Los ordenamos en funcion de su distancia
            matches = sorted(matches, key=lambda x: x.distance)
            N = len(matches)
            M = int(math.floor(
                0.6 *
                N))  # seleccionaremos el 60% de los puntos con menor distancia

            if M > MIN_MATCH_COUNT:
                train_pts = np.float32([
                    self.train_kp[m.queryIdx].pt for m in matches[:M]
                ]).reshape(-1, 1, 2)
                curr_pts = np.float32([
                    self.curr_kp[m.trainIdx].pt for m in matches[:M]
                ]).reshape(-1, 1, 2)

                H, mask = cv2.findHomography(train_pts, curr_pts, cv2.RANSAC,
                                             5.0)
                matchesMask = mask.ravel().tolist()
                h, w, d = self.train_img.shape
                pts = np.float32([[0, 0], [0, h - 1], [w - 1, h - 1],
                                  [w - 1, 0]]).reshape(-1, 1, 2)
                dst = cv2.perspectiveTransform(pts, H)
                img_det = cv2.polylines(self.cv_image, [np.int32(dst)], True,
                                        (255, 255, 255), 3, cv2.LINE_AA)
            else:
                print "Not enough matches are found - %d/%d" % (
                    M, MIN_MATCH_COUNT)
                matchesMask = None

            # parametros de dibujo
            draw_params = dict(
                matchColor=(0, 255, 0),  # dibujar matches en verde
                singlePointColor=None,
                matchesMask=matchesMask,  # dibujar solo inliers
                flags=2)
            img_det2 = cv2.drawMatches(self.train_img, self.train_kp, img_det,
                                       self.curr_kp, matches[:M], None,
                                       **draw_params)

            # publicamos la imagen al topico /image/detection
            try:
                self.pub_det.publish(
                    self.bridge.cv2_to_imgmsg(img_det2, "bgr8"))
            except CvBridgeError as e:
                print('Homography')
                print(e)

    def clipAndCrop(self, event, x, y, flags, param):
        #referencia: http://www.pyimagesearch.com/2015/03/09/capturing-mouse-click-events-with-python-and-opencv/
        # if the left mouse button was clicked, record the starting
        # (x, y) coordinates and indicate that cropping is being
        # performed
        if event == cv2.EVENT_LBUTTONDOWN:
            self.referencePoints = [(x, y)]
            self.cropping = True
        # check to see if the left mouse button was released
        elif (event == cv2.EVENT_LBUTTONUP and self.cropping):
            # record the ending (x, y) coordinates and indicate that
            # the cropping operation is finished

            self.referencePoints.append((x, y))
            cropping = False

            img_clone = self.cv_image.copy()

            # draw a rectangle around the region of interest
            cv2.rectangle(img_clone, self.referencePoints[0],
                          self.referencePoints[1], (0, 255, 0), 2)

            # calcular descriptores en imagen de entrenamiento
            self.train_img = img_clone[
                self.referencePoints[0][1]:self.referencePoints[1][1],
                self.referencePoints[0][0]:self.referencePoints[1][0]]
            train_gray = cv2.cvtColor(self.train_img, cv2.COLOR_BGR2GRAY)

            (self.train_kp, self.train_desc) = self.detector.detectAndCompute(
                train_gray, None)
            self.detect = True
            print('Imagen de entrenamiento capturada!')
            cv2.imshow('image', img_clone)
class DepthRegisterNode(object):
    '''class holding and performing ROS-related stuff like subscriptions, publishing, parameters and callbacks'''

    def __init__(self):
        rospy.init_node('simple_depth_register_node')
        self.cv_bridge = CvBridge()

        # extrinsics parameters (offset rgb cam -> depth cam), defaulting to realsense r200 values
        dx = rospy.get_param('~x_offset', -0.0589333333)
        dy = rospy.get_param('~y_offset', 0)
        dz = rospy.get_param('~z_offset', 0)

        # scale in which depth values are presented relative to meters
        depth_scale = rospy.get_param('~depth_scale', 1000.0) # 1000 is millimeters

        self.dr = DepthRegisterer(dx, dy, dz, depth_scale)

        # input topics
        rgb_topic = rospy.get_param('~rgb_topic', '/camera/rgb/image_raw')
        depth_topic = rospy.get_param('~depth_topic', '/camera/depth/image_raw')

        # read cameras' intrinsics
        rgb_info_topic, depth_info_topic = [t[:t.rfind('/')] + '/camera_info' for t in (rgb_topic, depth_topic)]
        self.camera_info_callback(rospy.wait_for_message(rgb_info_topic, CameraInfo), 'rgb')
        self.camera_info_callback(rospy.wait_for_message(depth_info_topic, CameraInfo), 'depth')
        rospy.loginfo('camera calibration data OK')

        # subscribe to input topics
        rgb_sub = message_filters.Subscriber(rgb_topic, Image)
        depth_sub = message_filters.Subscriber(depth_topic, Image)
        self.sub = message_filters.ApproximateTimeSynchronizer([rgb_sub, depth_sub], 3, 0.1)
        self.sub.registerCallback(self.image_pair_callback)
        rospy.loginfo('synchronized subscriber OK')

        # registered depth image output topic name
        registered_topic = rospy.get_param('~registered_topic', '~depth_registered')

        # announce output topics
        self.pub = rospy.Publisher(registered_topic, Image, queue_size=5)
        self.pub_info_unregistered = rospy.Publisher('~info_image_unregistered', Image, queue_size=5)
        self.pub_info_registered = rospy.Publisher('~info_image_registered', Image, queue_size=5)

        self.rgb_image = None
        self.depth_image = None
        self.registered_depth_image = None

    def camera_info_callback(self, msg_camera_info, cam_id):
        '''passes the intrinsics of a camera_info message to the depth registerer'''
        fx, _, cx, _, fy, cy, _, _, _ = msg_camera_info.K
        self.dr.set_intrinsics(cam_id, fx, fy, cx, cy)

    def image_pair_callback(self, msg_rgb_image, msg_depth_image):
        '''makes the depth registerer process the image pair and produces output images'''
        # convert images ROS -> OpenCV
        try:
            self.rgb_image = self.cv_bridge.imgmsg_to_cv2(msg_rgb_image, "rgb8")
        except CvBridgeError as e:
            rospy.logwarn('error converting rgb image: %s' % e)
            return
        try:
            self.depth_image = self.cv_bridge.imgmsg_to_cv2(msg_depth_image)
        except CvBridgeError as e:
            rospy.logwarn('error converting depth image: %s' % e)
            return

        # be lazy, check subscriber count first
        has_depth_subs = self.pub.get_num_connections() > 0
        has_info_subs = (self.pub_info_unregistered.get_num_connections() + self.pub_info_registered.get_num_connections()) > 0
        has_subs = has_depth_subs or has_info_subs

        if has_subs:
            # processing
            self.registered_depth_image = self.dr.register(self.rgb_image, self.depth_image)
            # convert image OpenCV -> ROS and send out
            msg = self.cv_bridge.cv2_to_imgmsg(self.registered_depth_image)
            msg.header.stamp = msg_depth_image.header.stamp
            self.pub.publish(msg)

            if has_info_subs:
                # send out info images
                img_unregistered_img, img_registered_img = self.get_info_images()
                self.pub_info_unregistered.publish(self.cv_bridge.cv2_to_imgmsg(img_unregistered_img, "rgb8"))
                self.pub_info_registered.publish(self.cv_bridge.cv2_to_imgmsg(img_registered_img, "rgb8"))

    def get_info_images(self):
        '''generates one registered and one unregistered blended image of rgb and depth image'''
        # clip depth values to a certain maximum and scale constantly wrt. this value to avoid jitter
        clipping_distance = 5. # meters
        # clip
        depth_image = self.depth_image / (clipping_distance * self.dr.depth_scale) * 255.
        depth_image[depth_image > 255] = 255
        # resize to fit rgb image and convert to 24-bit bgr
        depth_image = cv2.cvtColor(cv2.resize(depth_image.astype('uint8'), (self.rgb_image.shape[1], self.rgb_image.shape[0]), interpolation=cv2.INTER_NEAREST), cv2.COLOR_GRAY2BGR)

        # clip
        registered_depth_image = self.registered_depth_image.astype(float) * 255. / clipping_distance
        registered_depth_image[registered_depth_image > 255] = 255
        # convert to 24-bit bgr
        registered_depth_image = cv2.cvtColor(registered_depth_image.astype('uint8'), cv2.COLOR_GRAY2BGR)

        # blend
        return cv2.addWeighted(self.rgb_image, 0.5, depth_image, 0.5, 0), cv2.addWeighted(self.rgb_image, 0.5, registered_depth_image, 0.5, 0)

    def spin(self):
        '''stayin' alive'''
        rospy.spin()
class PersonDetector():
    def __init__(self):

        # cv_bridge handles
        self.cv_bridge = CvBridge()

        self.person_bbox = BoundingBox()

        # ROS PARAM
        self.m_pub_threshold = rospy.get_param('~pub_threshold', 0.70)

        # detect width height
        self.WIDTH  = 50
        self.HEIGHT = 50

        # Publish
        self.pub_cmd = rospy.Publisher('cmd_vel', Twist, queue_size=10)

        # Twist 型のデータ
        self.t = Twist()

        # Subscribe
        sub_camera_rgb    =  rospy.Subscriber('/camera/color/image_raw', Image, self.CamRgbImageCallback)
        sub_camera_depth  =  rospy.Subscriber('/camera/aligned_depth_to_color/image_raw', Image, self.CamDepthImageCallback)
        sub_darknet_bbox  =  rospy.Subscriber('/darknet_ros/bounding_boxes', BoundingBoxes, self.DarknetBboxCallback)

        return

    def CamRgbImageCallback(self, rgb_image_data):
        try:
            rgb_image = self.cv_bridge.imgmsg_to_cv2(rgb_image_data, 'passthrough')
        except CvBridgeError, e:
            rospy.logerr(e)

        rgb_image.flags.writeable = True
        rgb_image = cv2.cvtColor(rgb_image, cv2.COLOR_BGR2RGB)
        h, w, c = rgb_image.shape

        # 人がいる場合
        if self.person_bbox.probability > 0.0:

            x_person = (int)(self.person_bbox.xmax+self.person_bbox.xmin)/2
            y_person = (int)(self.person_bbox.ymax+self.person_bbox.ymin)/2

            x1 = (w / 2) - self.WIDTH
            x2 = (w / 2) + self.WIDTH
            y1 = (h / 2) - self.HEIGHT
            y2 = (h / 2) + self.HEIGHT

            sum = 0.0
            for i in range(y1, y2):
                for j in range(x1, x2):
                    rgb_image.itemset((i, j, 0), 0)
                    rgb_image.itemset((i, j, 1), 0)
                    if self.m_depth_image.item(i,j) == self.m_depth_image.item(i,j):
                        sum += self.m_depth_image.item(i,j)
    
            ave = sum / ((self.WIDTH * 2) * (self.HEIGHT * 2))
            #rospy.loginfo('Class : person, Score: %.2f, Dist: %dmm ' %(self.person_bbox.probability, ave))
            print("%f [m]" % ave)
            
            velocity = 0
            rotation = 0
            error_angle = x_person - 320
            error_distance = ave - 150
            controll_angle_gain = 0.006
            controll_distance_gain = 0.0004

            if error_angle > 0 and ave > 300:
                velocity = controll_distance_gain * error_distance
                if velocity > 0.2:
                    velocity = 0.2
                rotation = -controll_angle_gain * error_angle
            elif error_angle < 0 and ave > 300:
                velocity = controll_distance_gain * error_distance
                if velocity > 0.2:
                    velocity = 0.2
                rotation = -controll_angle_gain * error_angle
            else:
                velocity = 0.0
                rotation = 0.0

            self.t.linear.x = velocity
            self.t.angular.z = rotation
            self.pub_cmd.publish(self.t)

            """
            cv2.normalize(self.m_depth_image, self.m_depth_image, 0, 1, cv2.NORM_MINMAX)
            cv2.namedWindow("color_image")
            cv2.namedWindow("depth_image")
            cv2.imshow("color_image", rgb_image)
            cv2.imshow("depth_image", self.m_depth_image)
            cv2.waitKey(10)
            """
            """
            cv2.rectangle(rgb_image, (self.person_bbox.xmin, self.person_bbox.ymin), (self.person_bbox.xmax, self.person_bbox.ymax),(0,0,255), 2)
            #rospy.loginfo('Class : person, Score: %.2f, Dist: %dmm ' %(self.person_bbox.probability, m_person_depth))
            text = "person " +('%dmm' % ave)
            text_top = (self.person_bbox.xmin, self.person_bbox.ymin - 10)
            text_bot = (self.person_bbox.xmin + 80, self.person_bbox.ymin + 5)
            text_pos = (self.person_bbox.xmin + 5, self.person_bbox.ymin)
            cv2.rectangle(rgb_image, text_top, text_bot, (0,0,0),-1)
            cv2.putText(rgb_image, text, text_pos, cv2.FONT_HERSHEY_SIMPLEX, 0.35, (255, 0, 255), 1)
            """
        """
        cv2.namedWindow("rgb_image")
        cv2.imshow("rgb_image", rgb_image)
        cv2.waitKey(10)
        cv2.normalize(self.m_depth_image, self.m_depth_image, 0, 32768, cv2.NORM_MINMAX)
        cv2.namedWindow("depth_image")
        cv2.imshow("depth_image", self.m_depth_image)
        cv2.waitKey(10)
        """
        return
Пример #37
0
def get_distance(img):
    global depth_image
    bridge = CvBridge()
    depth_image = bridge.imgmsg_to_cv2(img, desired_encoding="32FC1")
Пример #38
0
class image_converter:
    def __init__(self):
        self.image_pub = rospy.Publisher("trackedBall/camera1",
                                         Image,
                                         queue_size=10)
        self.location_pub = rospy.Publisher("locationBall/camera1",
                                            String,
                                            queue_size=10)
        self.bridge = CvBridge()
        self.image_sub = rospy.Subscriber("camera1/camera", Image,
                                          self.callback)

    def callback(self, data):
        try:
            cv_image = self.bridge.imgmsg_to_cv2(data, "bgr8")
        except CvBridgeError as e:
            print(e)

        #define boundaries of color (in this case green, HSV)
        greenLower = (29, 86, 6)
        greenUpper = (64, 255, 255)

        #resize for easier manipulation
        cv_image = imutils.resize(cv_image, width=600)
        #option to blur if needed
        # blurred = cv2.GaussianBlur(cv_image, (11, 11), 0)
        #recolor to HSV
        hsv = cv2.cvtColor(cv_image, cv2.COLOR_BGR2HSV)

        #construct masks for the green color, then remove blobs
        mask = cv2.inRange(hsv, greenLower, greenUpper)
        mask = cv2.erode(mask, None, iterations=2)
        mask = cv2.dilate(mask, None, iterations=2)

        #find contours in mask and initialize center of ball (x,y)
        cnts = cv2.findContours(mask.copy(), cv2.RETR_EXTERNAL,
                                cv2.CHAIN_APPROX_SIMPLE)[-2]
        center = None

        #proceed if at least one contour was found.
        if len(cnts) > 0:
            # find the largest contour in the mask, then use
            # it to compute the minimum enclosing circle and
            # centroid
            c = max(cnts, key=cv2.contourArea)
            ((x, y), radius) = cv2.minEnclosingCircle(c)
            M = cv2.moments(c)
            center = (int(M["m10"] / M["m00"]), int(M["m01"] / M["m00"]))

            # only proceed if radius meets a minimum size
            if radius > 10:
                # draw the circle and centroid on the frame,
                # then update the list of tracked points
                cv2.circle(cv_image, (int(x), int(y)), int(radius),
                           (0, 255, 255), 2)
                cv2.circle(cv_image, center, 3, (0, 0, 255), -1)

        cv2.imshow("Image window", cv_image)

        cv2.waitKey(3)

        try:
            self.image_pub.publish(self.bridge.cv2_to_imgmsg(cv_image, "bgr8"))
            self.location_pub.publish(center)

        except CvBridgeError as e:
            print(e)
Пример #39
0
class TLDetector(object):
    ''' Contructor.
    '''
    def __init__(self):
        rospy.init_node('tl_detector')

        self.use_ground_truth = USE_GROUND_TRUTH

        # Traffic light classifier's thread and its task queue.
        self.image_processing = False
        self.queue = Queue()
        self.light_classifier = TLClassifier(self.queue, self.classified_cb)
        self.light_classifier.daemon = True
        self.light_classifier.start()

        self.config = yaml.load(rospy.get_param("/traffic_light_config"))
        self.cv_bridge = CvBridge()
        self.state = TrafficLight.UNKNOWN
        self.last_state = TrafficLight.UNKNOWN
        self.last_wp = -1
        self.state_count = 0
        self.next_waypoint_ahead = None
        self.waypoints = None
        self.traffic_lights = RouteTrafficLights()

        # Subscribers.
        sub0 = rospy.Subscriber('/next_waypoint_ahead', Int32, self.wp_cb)
        sub1 = rospy.Subscriber('/base_waypoints', Lane, self.waypoints_cb)
        sub2 = rospy.Subscriber('/image_color', Image, self.image_cb)
        '''
        /vehicle/traffic_lights provides the location of the traffic light in 3D
        map space and helps to acquire an accurate ground truth data source for
        the traffic light classifier by sending the current color state of all
        traffic lights in the simulator. When testing on the vehicle, the color
        state will not be available.
        '''
        sub3 = rospy.Subscriber('/vehicle/traffic_lights', TrafficLightArray,
                                self.traffic_cb)

        # Publishers.
        self.upcoming_red_light_pub = rospy.Publisher('/traffic_waypoint',
                                                      Int32,
                                                      queue_size=1)
        rospy.spin()

    def wp_cb(self, msg):
        ''' Dispatches a message from topic /next_waypoint_ahead.
        Args:
            msg (Int32): Index of the next waypoint ahead.
        '''
        self.next_waypoint_ahead = msg.data

    def waypoints_cb(self, waypoints):
        ''' Dispatches a message from topic /base_waypoints.
        Args:
            waypoints (Lane): Waypoints of the track.
        '''
        self.waypoints = list(waypoints.waypoints)
        # Reset traffic light information on each route update.
        self.traffic_lights.reset(self.waypoints,
                                  self.config['stop_line_positions'])

    def traffic_cb(self, msg):
        ''' Dispatches a message from topic /vehicle/traffic_lights.
        Args:
            msg (TrafficLightArray): Traffic light data.
        '''
        self.traffic_lights.update_states(msg.lights)

    def image_cb(self, msg):
        ''' Dispatches a message from topic /image_color.
        Args:
            msg (Image): image from car-mounted camera.
        '''
        light_wp = -1
        light_state = TrafficLight.UNKNOWN
        light_key = None
        if self.next_waypoint_ahead:
            # Get next traffic light ahead.
            light_wp, light_key = \
                self.traffic_lights.get_next_en_route(self.next_waypoint_ahead)

        if light_key == None:
            # Next light key is unknown so as the light state.
            self.publish_red_light(light_wp, light_state)
        else:
            # Distance in waypoints in a circular track.
            d = lambda x, y, s: (x - y + s) % s
            stop_point = self.traffic_lights[light_key].stop_point
            if d(stop_point, self.next_waypoint_ahead, len(self.waypoints)) \
                    > LIGHT_DETECTION_DISTANCE:
                # Next traffic light is too far, its state is unknown.
                self.publish_red_light(light_wp, light_state)
            else:
                # Get state of next waypoint from either simulator or image.
                if self.use_ground_truth:
                    self.detect_light_state_from_gt(light_wp, light_key)
                else:
                    self.detect_light_state_from_img(light_wp, msg)

    def classified_cb(self, light_wp, light_state):
        ''' Dispatches the traffic light classification result.
        Args:
            light_wp (Int32): Index of the traffic light's waypoint.
            light_state (TrafficLight): State of the traffic light.
        '''
        self.image_processing = False
        self.publish_red_light(light_wp, light_state)

    def detect_light_state_from_img(self, light_wp, image_msg):
        ''' Detects and classifies traffic lights in the image message.
        Args:
            light_wp (Int32): Index of the traffic light's waypoint.
            image_msg (Image): Image from car-mounted camera.
        '''
        if not self.image_processing:
            image = self.cv_bridge.imgmsg_to_cv2(image_msg, "bgr8")
            self.image_processing = True
            self.queue.put((light_wp, image))

    def detect_light_state_from_gt(self, light_wp, light_key):
        ''' Detects and classifies traffic lights from the ground truth.
        Args:
            light_wp (Int32): Index of the traffic light's waypoint.
            light_key: Index of the traffic light.
        '''
        light_state = self.traffic_lights[light_key].state
        self.publish_red_light(light_wp, light_state)

    def publish_red_light(self, light_wp, light_state):
        ''' Publishes the index of the waypoint closest to the red light's stop
            line to /traffic_waypoint. Each predicted state has to occur
            STATE_COUNT_THRESHOLD number of times till we start using it.
            Otherwise the previous stable state is used.
        Args:
            light_wp (Int32): Index of the traffic light's waypoint.
            light_state (TrafficLight): State of the traffic light.
        '''
        rospy.logdebug("publish_red_light: light_wp %d, light_state %d",
                       light_wp, light_state)
        if self.state != light_state:
            self.state_count = 0
            self.state = light_state
        elif self.state_count >= STATE_COUNT_THRESHOLD:
            self.last_state = self.state
            light_wp = light_wp \
                if light_state in (TrafficLight.RED, TrafficLight.YELLOW) \
                else -1
            self.last_wp = light_wp
            self.upcoming_red_light_pub.publish(Int32(light_wp))
        else:
            self.upcoming_red_light_pub.publish(Int32(self.last_wp))
        self.state_count += 1
Пример #40
0
class DepthController:
    MM_IN_M = 1000

    def __init__(
        self,
        distance_threshold,
        num_angles,
        sphere_radius,
        step_len,
        debug,
        steer_multiplier,
        horizontal_stretch,
    ):
        self.distance_threshold = distance_threshold
        self.num_angles = num_angles
        self.sphere_radius = sphere_radius
        self.step_len = step_len
        self.debug = debug

        self.steer_multiplier = steer_multiplier
        self.horizontal_stretch = horizontal_stretch

        self.pub_servo = rospy.Publisher('/servo', Int16, queue_size=1)
        self.pub_esc = rospy.Publisher('/esc', Int16, queue_size=1)

        self.bridge = CvBridge()

        rospy.Subscriber('/camera/aligned_depth_to_color/image_raw', Image,
                         self._depth_cb)

        if self.debug:
            self.pub_debug_image = rospy.Publisher('/debug_image',
                                                   Image,
                                                   queue_size=1)

        self.servo_neutral = 1479
        self.servo_range = 500
        self.esc_neutral = 1500

        self.angle_mult = 600  #80 # 600
        self.throt_mult = 200  # 80 # 200

        rospy.Subscriber('/joy', Joy, self._joy_cb, queue_size=1)

        rospy.init_node('depth_controller')

    def _depth_cb(self, msg):
        self.depth_frame = self.bridge.imgmsg_to_cv2(
            msg, desired_encoding='passthrough').astype(
                np.float) / self.MM_IN_M

    def spin(self):
        rate = rospy.Rate(100)
        while not rospy.is_shutdown():
            self.choose_angle()

    def choose_angle(self):
        if self.depth_frame is None:
            return

        # Makes the code a bit less cluttered
        depth_frame = self.depth_frame

        depth_frame[depth_frame > self.distance_threshold] = np.nan
        depth_frame[depth_frame == 0] = np.nan

        start_time = time.time()
        waypoints, frame = find_waypoints(
            depth_frame,
            horizontal_stretch=self.horizontal_stretch,
            statistic=np.nanmean,
            num_angles=self.num_angles,
            step_len=self.step_len,
            sphere_radius=self.sphere_radius,
            draw_waypoints=self.debug,
        )

        if self.debug:
            delta = time.time() - start_time
            rospy.loginfo('Finding waypoints took: {:.1f}ms'.format(1000 *
                                                                    delta))

            # Also, publish an image for debugging
            depth_frame[np.isnan(depth_frame)] = 0
            depth_frame -= depth_frame.min()
            depth_frame = 127 * (depth_frame / depth_frame.max())
            debug_image = image.numpy_to_image(depth_frame.astype('uint8'),
                                               encoding='mono8')
            self.pub_debug_image.publish(debug_image)

        start_time = time.time()
        angle = find_angle(waypoints)

        if self.debug:
            delta = time.time() - start_time
            rospy.loginfo('Finding angle took: {:.1f}ms'.format(1000 * delta))

        angle = self.servo_neutral + int(
            self.steer_multiplier * angle * self.servo_range)

        self.pub_servo.publish(angle)

    def _joy_cb(self, msg):
        throt = msg.axes[3]
        throt = self.esc_neutral + int(self.throt_mult * throt)

        self.pub_esc.publish(throt)
Пример #41
0
 def edge_callback(self, data):
     bridge = CvBridge()
     global edge_image
     edge_image = bridge.imgmsg_to_cv2(data, "mono8")
Пример #42
0
class AllSensorBot(object):
    def __init__(self, 
                 use_lidar=False, use_camera=False, use_imu=False,
                 use_odom=False, use_joint_states=False):

        # velocity publisher
        self.vel_pub = rospy.Publisher('cmd_vel', Twist,queue_size=1)

        # lidar scan subscriber
        if use_lidar:
            self.scan = LaserScan()
            self.lidar_sub = rospy.Subscriber('scan', LaserScan, self.lidarCallback)

        # camera subscribver
        # please uncoment out if you use camera
        if use_camera:
            # for convert image topic to opencv obj
            self.img = None
            self.bridge = CvBridge()
            self.image_sub = rospy.Subscriber('image_raw', Image, self.imageCallback)

        # imu subscriber
        if use_imu:
            self.imu_sub = rospy.Subscriber('imu', Imu, self.imuCallback)

        # odom subscriber
        if use_odom:
            self.odom_sub = rospy.Subscriber('odom', Odometry, self.odomCallback)

        # joint_states subscriber
        if use_joint_states:
            self.odom_sub = rospy.Subscriber('joint_states', JointState, self.jointstateCallback)

    def strategy(self):
        '''
        calc Twist and publish cmd_vel topic
        '''
        r = rospy.Rate(1)

        while not rospy.is_shutdown():
            # update twist
            twist = Twist()
            //twist.linear.x = 0.1; twist.linear.y = 0; twist.linear.z = 0
            //twist.angular.x = 0; twist.angular.y = 0; twist.angular.z = 0

            # publish twist topic
            self.vel_pub.publish(twist)
            r.sleep()


    # lidar scan topic call back sample
    # update lidar scan state
    def lidarCallback(self, data):
        self.scan = data
        rospy.loginfo(self.scan)

    # camera image call back sample
    # comvert image topic to opencv object and show
    def imageCallback(self, data):
        try:
            self.img = self.bridge.imgmsg_to_cv2(data, "bgr8")
        except CvBridgeError as e:
            rospy.logerr(e)

        cv2.imshow("Image window", self.img)
        cv2.waitKey(1)

    # imu call back sample
    # update imu state
    def imuCallback(self, data):
        self.imu = data
        rospy.loginfo(self.imu)

    # odom call back sample
    # update odometry state
    def odomCallback(self, data):
        self.pose_x = data.pose.pose.position.x
        self.pose_y = data.pose.pose.position.y
        rospy.loginfo("odom pose_x: {}".format(self.pose_x))
        rospy.loginfo("odom pose_y: {}".format(self.pose_y))

    # jointstate call back sample
    # update joint state
    def jointstateCallback(self, data):
        self.wheel_rot_r = data.position[0]
        self.wheel_rot_l = data.position[1]
        rospy.loginfo("joint_state R: {}".format(self.wheel_rot_r))
        rospy.loginfo("joint_state L: {}".format(self.wheel_rot_l))
class Detector:

    def __init__(self):
        self.image_pub = rospy.Publisher("debug_image",Image, queue_size=1)
        self.object_pub = rospy.Publisher("~objects", Detection2DArray, queue_size=1)
        self.bridge = CvBridge()
        self.image_sub = rospy.Subscriber("image", Image, self.image_cb, queue_size=1, buff_size=2**24)
        self.sess = tf.Session(graph=detection_graph,config=config)

        # load the label map into the ROS parameter server as a list of strings of labels
        rospy.set_param( "~labels", {str(c['id']): c['name'] for c in categories} )

        # advertise that the detector node is ready
        rospy.Service( 'check_is_ready', CheckIsReady, self.check_is_ready )


    def check_is_ready(self, req):
        return True
    
        
    def image_cb(self, data):
        objArray = Detection2DArray()
        try:
            cv_image = self.bridge.imgmsg_to_cv2(data, "bgr8")
        except CvBridgeError as e:
            print(e)
        image=cv2.cvtColor(cv_image,cv2.COLOR_BGR2RGB)

        # the array based representation of the image will be used later in order to prepare the
        # result image with boxes and labels on it.
        image_np = np.asarray(image)
        # Expand dimensions since the model expects images to have shape: [1, None, None, 3]
        image_np_expanded = np.expand_dims(image_np, axis=0)
        image_tensor = detection_graph.get_tensor_by_name('image_tensor:0')
        # Each box represents a part of the image where a particular object was detected.
        boxes = detection_graph.get_tensor_by_name('detection_boxes:0')
        # Each score represent how level of confidence for each of the objects.
        # Score is shown on the result image, together with the class label.
        scores = detection_graph.get_tensor_by_name('detection_scores:0')
        classes = detection_graph.get_tensor_by_name('detection_classes:0')
        num_detections = detection_graph.get_tensor_by_name('num_detections:0')

        (boxes, scores, classes, num_detections) = self.sess.run([boxes, scores, classes, num_detections],
            feed_dict={image_tensor: image_np_expanded})

        objects=vis_util.visualize_boxes_and_labels_on_image_array(
            image,
            np.squeeze(boxes),
            np.squeeze(classes).astype(np.int32),
            np.squeeze(scores),
            category_index,
            use_normalized_coordinates=True,
            line_thickness=2)

        objArray.detections =[]
        objArray.header=data.header
        object_count=1

        for i in range(len(objects)):
            object_count+=1
            objArray.detections.append(self.object_predict(objects[i],data.header,image_np,cv_image))

        self.object_pub.publish(objArray)

        img=cv2.cvtColor(image_np, cv2.COLOR_BGR2RGB)
        image_out = Image()
        try:
            image_out = self.bridge.cv2_to_imgmsg(img,"bgr8")
        except CvBridgeError as e:
            print(e)
        image_out.header = data.header
        self.image_pub.publish(image_out)

    def object_predict(self,object_data, header, image_np,image):
        image_height,image_width,channels = image.shape
        obj=Detection2D()
        obj_hypothesis= ObjectHypothesisWithPose()

        object_id=object_data[0]
        object_score=object_data[1]
        dimensions=object_data[2]

        obj.header=header
        obj_hypothesis.id = object_id
        obj_hypothesis.score = object_score
        obj.results.append(obj_hypothesis)
        obj.bbox.size_y = int((dimensions[2]-dimensions[0])*image_height)
        obj.bbox.size_x = int((dimensions[3]-dimensions[1] )*image_width)
        obj.bbox.center.x = int((dimensions[1]+0.5*(dimensions[3]-dimensions[1]))*image_width)
        obj.bbox.center.y = int((dimensions[0]+0.5*(dimensions[2]-dimensions[0]))*image_height)

        return obj
Пример #44
0
class MiDaSROS:
    def __init__(self):
        '''Initialize ros publisher, ros subscriber'''
        # topic where we publish
        self.bridge = CvBridge()
        self.image_depth_pub = rospy.Publisher("/midas/depth/image_raw",
                                               Image,
                                               queue_size=1)
        self.image_rgb_pub = rospy.Publisher("/midas/rgb/image_raw",
                                             Image,
                                             queue_size=1)
        self.camera_info_pub = rospy.Publisher("/midas/camera_info",
                                               CameraInfo,
                                               queue_size=1)

        # subscribed Topic
        self.subscriber = rospy.Subscriber("/midas_rgb/image_raw",
                                           Image,
                                           self.callback,
                                           queue_size=1)

        # setup image display
        self.display_rgb = False
        self.display_depth = True

        # initialize Intel MiDas
        self.initialized_midas = False
        rospack = rospkg.RosPack()
        ros_pkg_path = rospack.get_path('intelisl_midas_ros')
        model_path = os.path.join(ros_pkg_path, 'src/model-f6b98070.pt')

        self.model = MidasNet(model_path, non_negative=True)
        self.device = torch.device(
            "cuda") if torch.cuda.is_available() else torch.device("cpu")
        self.model.to(self.device)
        self.model.eval()
        rospy.loginfo('Loaded Intel MiDaS')

        midas_transforms = torch.hub.load("intel-isl/MiDaS", "transforms")
        self.transform = midas_transforms.default_transform
        rospy.loginfo('Initialized Intel MiDaS transform')
        self.initialized_midas = True

    def show_image(self, img, window_name="Image Window"):
        cv2.namedWindow(window_name, cv2.WINDOW_NORMAL)
        cv2.imshow(window_name, img)
        cv2.waitKey(2)

    def callback(self, img_msg):
        # conversion to OpenCV and the correct color
        img = cv2.cvtColor(
            self.bridge.imgmsg_to_cv2(img_msg, desired_encoding='passthrough'),
            cv2.COLOR_BGR2RGB)
        if self.display_rgb:
            self.show_image(img, window_name='Ground Truth RGB')

        # convert RGB to depth using MiDaS
        if self.initialized_midas:
            input_batch = self.transform(img).to(self.device)
            with torch.no_grad():
                prediction = self.model(input_batch)
                prediction = torch.nn.functional.interpolate(
                    prediction.unsqueeze(1),
                    size=img.shape[:2],
                    mode="bicubic",
                    align_corners=False,
                ).squeeze()

            # scale pixel values to display
            omax, omin = prediction.max(), prediction.min()
            prediction = (prediction - omin) / (omax - omin)

            # convert depth prediction to numpy
            output = prediction.cpu().numpy()
            if self.display_depth:
                self.show_image(output, window_name='Estimated Depth')

            # setup message (depth)
            depth_msg = self.bridge.cv2_to_imgmsg(output,
                                                  encoding="passthrough")

            # setup message camera info
            camera_info_msg = CameraInfo()
            camera_info_msg.header.stamp = img_msg.header.stamp
            camera_info_msg.height = img.shape[0]
            camera_info_msg.width = img.shape[1]

            # publish
            self.image_depth_pub.publish(depth_msg)
            self.image_rgb_pub.publish(img_msg)
            self.camera_info_pub.publish(camera_info_msg)
Пример #45
0
class image_converter:

    global lines

    def __init__(self):
        self.start = 0
        self.pitch = 0
        self.yaw = 0
        self.po_dao = 0
        self.count = 0
        self.last_error = 0
        self.pd_ping_flag = 0
        self.last_rr = np.zeros((179, 1))
        self.last_ll = np.zeros((179, 1))
        self.bmx_flag = 0
        self.last_img = np.empty([180, 320])
        self.image_pub = rospy.Publisher("image_topic_2", Image)
        self.pub = rospy.Publisher('/cv/error', String)  #发布话题
        self.sub_imu = rospy.Subscriber('/imu_data', Imu, self.imu_callback)
        self.bridge = CvBridge()
        self.a = cv2.imread('./100.png')
        self.h, self.w = self.a.shape[:2]
        self.pts = np.float32([[50, 100], [263, 100], [0, 180], [319, 180]])
        self.pts1 = np.float32([[0, 0], [self.w - 1, 0], [0, self.h - 1],
                                [self.w - 1, self.h - 1]])
        self.m = cv2.getPerspectiveTransform(self.pts, self.pts1)
        #  self.image_sub = rospy.Subscriber("/usb_cam/image_raw",Image,self.callback)
        self.image_sub = rospy.Subscriber("/cv_camera/image_raw", Image,
                                          self.callback)

    def clean_flag(self):
        self.bmx_flag = 0
        self.po_dao = 0
        self.pd_ping_flag = 0

    def rgb_hls_lab(self, img):
        img_lab = cv2.cvtColor(img, cv2.COLOR_BGR2LAB)  #提取黄色   b通道
        img_hls = cv2.cvtColor(img, cv2.COLOR_BGR2HLS)  #提取白色   l通道
        imghls_h = img_hls[:, :, 0]
        imghls_l = img_hls[:, :, 1]
        imghls_s = img_hls[:, :, 2]
        #gray = cv2.equalizeHist(gray)

        imglab_l = img_lab[:, :, 0]
        imglab_a = img_lab[:, :, 1]
        imglab_b = img_lab[:, :, 2]

        retval_lab, dst_lab = cv2.threshold(imglab_b, 170, 255,
                                            cv2.THRESH_BINARY)
        retval_hls, dst_hls = cv2.threshold(imghls_l, 180, 255,
                                            cv2.THRESH_BINARY)

        #  imglab_b = cv2.equalizeHist(imglab_b)
        #  imghls_l = cv2.equalizeHist(imghls_l)
        #hls_lab = np.zeros_like(dst_lab)
        # hls_lab = dst_lab + dst_hls
        # cv2.imshow('b',dst_lab)
        # cv2.imshow('l',dst_hls)
        #cv2.imshow('b',imglab_b)
        print(dst_hls.shape[0])
        print(dst_hls.shape[1])
        count = np.sum(dst_hls) / 255
        print('white_count', count)

        cv2.imshow('l', imghls_l)
        cv2.imshow('l_', dst_hls)
        #  if count > 17000 and self.bmx_flag == 0:
        #     self.bmx_flag = 1
        #    t = Timer(2.0,self.clean_flag)
        #    t.start()
        #cv2.imshow('hls_lab',hls_lab)
        return count

    def extract(self, img):  #找到距离中心线最近的4个轮廓
        img_height = 180
        img_width = 320

        blur = cv2.GaussianBlur(img, (3, 3), 0, 0)
        gray = cv2.cvtColor(blur, cv2.COLOR_BGR2GRAY)
        gray_cp = gray[59:179, :]
        mid = np.median(gray_cp)
        min_thresh = (int)(mid * 0.66)
        max_thresh = (int)(mid * 1.33)
        #gray = cv2.equalizeHist(gray)
        #edges = cv2.Canny(gray,50,200)
        edges = cv2.Canny(gray, min_thresh, max_thresh)
        temp = np.ones(edges.shape, np.uint8) * 255  #白色幕布
        cv2.rectangle(edges, (0, 0), (319, 60), 0, -1)
        cv2.imshow('qiege', edges)

        h = cv2.findContours(edges, cv2.RETR_TREE, cv2.CHAIN_APPROX_NONE)
        contours = h[1]
        contours = [
            contour for contour in contours
            if ((abs)(cv2.fitLine(contour, cv2.DIST_L2, 0.2, 0.01, 0.01)[1] /
                      cv2.fitLine(contour, cv2.DIST_L2, 0.2, 0.01, 0.01)[0]) >
                0.45 and len(contour) > 100)
        ]
        contours_bmx = [contour for contour in contours if len(contour) > 200]
        print('wai', len(contours))
        if self.pitch > 25 and len(contours) >= 12 and self.pd_ping_flag == 0:
            self.pd_ping_flag = 1
            t = Timer(2.0, self.clean_flag)
            t.start()
        print('bmx', len(contours_bmx))
        if (len(contours_bmx) >= 9 and self.bmx_flag == 0 and self.pitch < 8):
            self.bmx_flag = 1
            t = Timer(2.0, self.clean_flag)
            t.start()
        cv2.drawContours(temp, contours, -1, (0, 255, 0), cv2.FILLED)
        cv2.imshow('contours', temp)
        return contours, temp

    def imu_data_deal(self):
        error = 0
        percent = (abs)(self.yaw) / 360
        yaw = abs(self.yaw)
        if (percent <= 0.125 or percent > 0.875):
            if (percent <= 0.125):
                error = yaw - 0
            elif (percent > 0.875):
                error = yaw - 360
        elif (percent > 0.125 and percent <= 0.375):
            error = yaw - 90
        elif (percent > 0.375 and percent <= 0.625):
            error = yaw - 180
        elif (percent > 0.625 and percent <= 0.875):
            error = yaw - 270
        return error

    def transform(self, img, transform_param):  #透视变换
        dst = cv2.warpPerspective(img, transform_param, (320, 180))
        cv2.imshow('dst', dst)
        return dst

    def counts_select(self, contours, img_ed, img):  #中线提取
        img_cp = np.copy(img_ed)  #副本图像
        img_height = 180
        img_width = 320

        point_list_l = []
        point_list_r = []
        contour_position = 'l'
        ll_q = 0
        rr_q = 0
        # print ('start',len(contours))
        point_listr = []
        point_listr_index = []
        point_listl = []
        point_listl_index = []
        count_l = 0
        count_r = 0
        for contour in contours:
            rows, cols = img_cp.shape[:2]
            [vx, vy, x_, y_] = cv2.fitLine(contour, cv2.DIST_L2, 0.2, 0.01,
                                           0.01)
            pose_x, pose_y, pose_w, pose_h = cv2.boundingRect(contour)
            if (pose_w >= 25 and vy / vx < 0):
                count_l = count_l + 1
            elif (pose_w >= 25 and vy / vx > 0):
                count_r = count_r + 1

            if (pose_w >= 50 and vy / vx < 0) or (
                    pose_w < 50 and
                (pose_x + pose_w + pose_x) / 2 <= img_width / 2):
                contour_position = 'l'
                ll_q = ll_q + pose_w
                point_listl_index.append(pose_x)
                point_listl.append(contour)

            if (pose_w >= 50 and vy / vx > 0) or (
                    pose_w < 50 and
                (pose_x + pose_w + pose_x) / 2 >= img_width / 2):
                contour_position = 'r'
                rr_q = rr_q + pose_w
                point_listr_index.append(pose_x)
                point_listr.append(contour)
            else:
                continue

        print('l,r', count_l, count_r)
        find_countl = 0
        find_countr = 0
        if len(contours) <= 1:
            find_countl = len(contours)
            find_countr = len(contours)
        else:
            find_countr = 1
            find_countl = 1
        dis_minr = (heapq.nsmallest(find_countr, point_listr_index))
        dis_minl = (heapq.nlargest(find_countl, point_listl_index))
        deal_contoursl = []
        deal_contoursr = []
        for i in dis_minl:
            index = point_listl_index.index(i)
            deal_contoursl.append(point_listl[index])
        for i in dis_minr:
            index = point_listr_index.index(i)
            deal_contoursr.append(point_listr[index])
        if (ll_q - rr_q >= 100 or count_l - count_r >= 2):
            for contour in deal_contoursl:
                for pose in contour:
                    x = pose[0][0]
                    y = pose[0][1]
                    point = (x, y)
                    if y >= (int)(img_height / 5):
                        point_list_l.append(point)
        elif (rr_q - ll_q >= 100 or count_r - count_l >= 2):
            for contour in deal_contoursr:
                #[vxl,vyl,xl_,yl_] = cv2.fitLine(np.array(contour),cv2.DIST_L2,0.2,0.01,0.01)
                for pose in contour:
                    x = pose[0][0]
                    y = pose[0][1]
                    point = (x, y)
                    if y >= (int)(img_height / 5):
                        point_list_r.append(point)
        elif (abs)(rr_q - ll_q) < 100:
            for contour in point_listl:
                for pose in contour:
                    x = pose[0][0]
                    y = pose[0][1]
                    point = (x, y)
                    if y >= (int)(img_height / 5):
                        point_list_l.append(point)
            for contour in point_listr:
                for pose in contour:
                    x = pose[0][0]
                    y = pose[0][1]
                    point = (x, y)
                    if y >= (int)(img_height / 5):
                        point_list_r.append(point)

    # print ('end')
        print('ll_q', ll_q)
        print('rr_q', rr_q)
        npl = np.mat(point_list_l)
        npr = np.mat(point_list_r)

        ll_ = np.zeros((img_height, 1))
        rr_ = np.full((img_height, 1), img_width - 1)
        width = np.full((img_height, 1), 0)
        for i in range(img_height):
            l = 40
            r = 280
            wid = r - l
            width[i] = wid

#把轮廓上杂乱的点 提取成左右线(一行只有一个点)
        for pose in npl:
            pose = pose.A  #必须要将矩阵转化为数组
            if (pose.shape[1] != 2):
                continue
            x = pose[0][0]
            y = pose[0][1]
            if (y > img_height - 120):
                if (ll_[y] == 0):
                    ll_[y] = x
                else:
                    if ll_[y] > x:
                        ll_[y] = ll_[y]
                    else:
                        ll_[y] = x

        for pose in npr:
            pose = pose.A  #必须要将矩阵转化为数组
            if (pose.shape[1] != 2):
                continue
            x = pose[0][0]
            y = pose[0][1]
            if (y > img_height - 120):
                if (rr_[y] == img_width - 1):
                    rr_[y] = x
                else:
                    if rr_[y] < x:
                        rr_[y] = rr_[y]
                    else:
                        rr_[y] = x

        point_deal_l = []
        point_deal_r = []
        for index, i in enumerate(ll_):
            if (index <= 60):
                continue
            if (i[0] == 0):
                if (rr_[index] == img_width - 1):
                    i[0] = 25
                    ll_[index] = 25
                else:
                    i[0] = rr_[index] - width[index]
                    ll_[index] = rr_[index] - width[index]
            pose = (int(i[0]), int(index))
            point_deal_l.append(pose)
        for index, i in enumerate(rr_):
            if (index <= 60):
                continue
            if (i[0] == img_width - 1):
                if (ll_[index] == 0):
                    i[0] = 295
                    rr_[index] = 295
                else:
                    i[0] = ll_[index] + width[index]
                    rr_[index] = ll_[index] + width[index]
            pose = (int(i[0]), int(index))
            point_deal_r.append(pose)
        [vxl, vyl, xl_, yl_] = cv2.fitLine(np.array(point_deal_l), cv2.DIST_L2,
                                           0.2, 0.01, 0.01)
        [vxr, vyr, xr_, yr_] = cv2.fitLine(np.array(point_deal_r), cv2.DIST_L2,
                                           0.2, 0.01, 0.01)
        kl = vyl / vxl
        kr = vyr / vxr
        for y, i in enumerate(ll_):
            if y < 60:
                continue
            if ((rr_[y] < ll_[y]) or ((abs)(rr_[y] - ll_[y]) < 40)):
                if (rr_q - ll_q > 125):
                    ll_[y] = rr_[y] - width[y]
                elif (ll_q - rr_q > 125):
                    rr_[y] = ll_[y] + width[y]
            if (kl > 1 and kr > 1):
                ll_[y] = rr_[y] - width[y]
            elif (kr < -1 and kl < -1):
                rr_[y] = ll_[y] + width[y]

        print('kl', vyl / vxl)
        print('kr', vyr / vxr)
        print(len(ll_), len(self.last_ll))
        for y in range(179):
            if (self.start == 0):
                self.start = 1
                break
            if y < 60:
                continue
            if (abs)(
                    self.last_ll[y] - ll_[y]
            ) > 50 and self.bmx_flag == 0 and self.po_dao == 0 and self.pd_ping_flag == 0:
                ll_[y] = self.last_ll[y]
            if (abs)(
                    self.last_rr[y] - rr_[y]
            ) > 50 and self.bmx_flag == 0 and self.po_dao == 0 and self.pd_ping_flag == 0:
                rr_[y] = self.last_rr[y]
        if self.bmx_flag == 1 or self.pd_ping_flag == 1:
            rr_ = np.full((img_height, 1), 280)
            ll_ = np.full((img_height, 1), 40)
        for index, i in enumerate(rr_):
            pose = ((int)(i[0]), int(index))
            cv2.circle(img, pose, 1, (255, 0, 0), 1)
        for index, i in enumerate(ll_):
            pose = (int(i[0]), int(index))
            cv2.circle(img, pose, 1, (255, 0, 255), 1)
        for index, i in enumerate(self.last_rr):
            pose = ((int)(i[0]), int(index))
            cv2.circle(img, pose, 1, (100, 0, 0), 1)
        for index, i in enumerate(self.last_ll):
            pose = (int(i[0]), int(index))
            cv2.circle(img, pose, 1, (255, 0, 100), 1)
        self.last_rr = rr_.copy()
        self.last_ll = ll_.copy()
        #得到中线
        mid = []
        for i in range(img_height):
            pose = ((int)((ll_[i] + rr_[i]) / 2), i)
            mid.append(pose)
#出中线
        for dian in mid:
            cv2.circle(img, dian, 1, (100, 0, 255), 1)

#画出基准线
        reference_line = []
        actual_line = []
        mid_value = 0
        start_raw = 80
        #    print ('pitch:')
        #    print (self.pitch)
        if ((self.pitch > 8 or self.pitch < -2) and self.po_dao == 0):
            self.po_dao = 1
            start_raw = 80
            t = Timer(2.0, self.clean_flag)
            t.start()
        self.pitch = float(self.pitch)
        self.yaw = round(self.yaw, 2)
        text_pitch = str(self.pitch)
        text_yaw = str(self.yaw)
        bmx_flag = str(self.bmx_flag)
        text_raw = str(start_raw)
        text_pd = str(self.po_dao)
        cv2.putText(img, text_pitch, (250, 50), cv2.FONT_HERSHEY_COMPLEX, 1.0,
                    (255, 255, 200), 2)
        cv2.putText(img, bmx_flag, (50, 100), cv2.FONT_HERSHEY_COMPLEX, 1.0,
                    (255, 255, 200), 2)
        cv2.putText(img, text_pd, (100, 100), cv2.FONT_HERSHEY_COMPLEX, 1.0,
                    (255, 255, 200), 2)
        cv2.putText(img, text_yaw, (0, 50), cv2.FONT_HERSHEY_COMPLEX, 1.0,
                    (255, 0, 200), 2)
        cv2.putText(img, text_raw, (250, 100), cv2.FONT_HERSHEY_COMPLEX, 1.0,
                    (255, 255, 200), 2)
        for i in range(10):  #计算60行的中值 求平均
            mid_value = mid_value + mid[start_raw + i][0]
            pose = (img_width / 2, start_raw + i)
            reference_line.append(pose)
        mid_value = (int)(mid_value / 10)

        print('mid_value', mid_value)
        for i in range(15):
            pose = (mid_value, 75 + i)
            actual_line.append(pose)

        for dian in reference_line:
            cv2.circle(img, dian, 1, (0, 255, 0), 1)
        for dian in actual_line:
            cv2.circle(img, dian, 1, (150, 255, 0), 1)
        error = mid_value - (img_width / 2) + (ll_q - rr_q) * 0.1
        if (self.bmx_flag == 1 or self.pd_ping_flag == 1):
            error = -self.imu_data_deal() * 10


#    if (abs)(error - self.last_error) > 150:
#        error = self.last_error
#pass
#    self.last_error = error
        error = float(error)
        text_error = str(error)
        cv2.putText(img, text_error, (100, 50), cv2.FONT_HERSHEY_COMPLEX, 1.0,
                    (255, 255, 200), 5)
        cv2.imshow("final", img)
        return error

    def imu_callback(self, data):
        self.pitch = data.orientation.y
        self.yaw = data.orientation.z

    def callback(self, data):
        try:
            cv_image = self.bridge.imgmsg_to_cv2(data, "bgr8")
        except CvBridgeError as e:
            print(e)
        start = time.time()
        img_cp = np.copy(cv_image)
        cv2.imshow('one', cv_image)

        transform_img = self.transform(cv_image, self.m)  #透视变换后的图像
        img_hl = self.rgb_hls_lab(transform_img)
        contours, edges = self.extract(transform_img)  #边缘提取后的轮廓和图像
        print(edges.shape)
        print(self.last_img.shape)
        cha = np.subtract(edges, self.last_img)
        cv2.imshow('img_cha', cha)
        #contours,edges = self.extract(bgr_img)     #边缘提取后的轮廓和图像
        self.last_img = np.copy(edges)
        cv2.imshow('img___', self.last_img)
        error = self.counts_select(contours, edges,
                                   transform_img)  #中线提取 最终得到偏差值
        #error = 0
        end = time.time()
        print('cost time', end - start)
        count = 0
        if self.bmx_flag == 1:
            str_zerba = 1
        else:
            str_zerba = 0
        str_error = "%d" % (error)  #将数字转换为字符串
        str_msg = str_error + " " + str(str_zerba)
        self.pub.publish(str_msg)  #发布偏差话题

        cv2.waitKey(3)
        try:
            self.image_pub.publish(self.bridge.cv2_to_imgmsg(cv_image, "bgr8"))
        except CvBridgeError as e:
            print(e)
Пример #46
0
 def stereo_callback(self, data):
     bridge = CvBridge()
     global cv_image
     cv_image = bridge.imgmsg_to_cv2(data, "mono8")
class ObjectDetectionNode:

    def __init__(self):
        self.camera_topic = rospy.get_param("/object_detection_node/camera_topic")
        self.obj_detect_results_topic = rospy.get_param("/object_detection_node/obj_detect_results_topic")
        self.obj_detect_viz_topic = rospy.get_param("/object_detection_node/obj_detect_viz_topic")

        rospy.init_node('object_detection')
        self.camera_sub = rospy.Subscriber(self.camera_topic,
            Image, self.image_update_callback, queue_size=1)
        self.current_frame = None
        self.bridge = CvBridge()

        rospy.loginfo("Object Detection Initializing")
        rospy.loginfo("Tiny Yolo V3")

        self.model_path = rospy.get_param("/object_detection_node/model_path")
        self.classes_path = rospy.get_param("/object_detection_node/classes_path")
        self.anchors_path = rospy.get_param("/object_detection_node/anchors_path")
        self.iou_threshold = rospy.get_param("/object_detection_node/iou_threshold")
        self.score_threshold = rospy.get_param("/object_detection_node/score_threshold")
        self.input_size = (416, 416)

        self.detector = ObjectDetector(model_path=self.model_path,
                                       classes_path=self.classes_path,
                                       anchors_path=self.anchors_path,
                                       score_threshold=self.score_threshold,
                                       iou_threshold=self.iou_threshold,
                                       size=self.input_size)

        labels_visualizer = utils.LabelsVisualizer(self.detector.class_names)
        detection_image_pub = rospy.Publisher(self.obj_detect_viz_topic + "/compressed",
            CompressedImage, queue_size=1)
        detection_results_pub = rospy.Publisher(self.obj_detect_results_topic,
            DetectionResults, queue_size=1)

        rate = rospy.Rate(15)

        while not rospy.is_shutdown():
            time = rospy.get_time()
            if self.current_frame is not None:
                print("new image at time %.2f" % time)
                out_boxes, out_scores, out_classes = \
                    self.detector.detect_object(self.current_frame)
                inference_end_time = rospy.get_time()
                print("*** inference time: %.3f" % (inference_end_time - time))

                if detection_image_pub.get_num_connections() > 0:
                    image = labels_visualizer.draw_bboxes(self.current_frame,
                        out_boxes, out_scores, out_classes)
                    print("***   drawing time: %.3f" % (rospy.get_time() - inference_end_time))

                    # img_msg = self.bridge.cv2_to_imgmsg(image, "bgr8")
                    msg = utils.cv2_to_compressed_imgmsg(image)
                    detection_image_pub.publish(msg)

                msg = self.convert_results_to_message(out_boxes, out_scores, out_classes)
                msg.is_green = self.check_traffic_segmentation(out_boxes, out_classes)
                if detection_results_pub.get_num_connections() > 0:
                    detection_results_pub.publish(msg)
            else:
                print("waiting for image at time %.2f" % time)
            rate.sleep()

    def check_traffic_segmentation(self, out_boxes, out_classes):
        labels = [self.detector.class_names[i] for i in out_classes]

        if 'TRAFFIC_LIGHT' not in labels:
            return True

        ind = labels.index('TRAFFIC_LIGHT')
        bbox = out_boxes[ind]

        top, left, bottom, right = bbox
        top = max(0, np.floor(top + 0.5).astype('int32'))
        left = max(0, np.floor(left + 0.5).astype('int32'))
        bottom = min(image.size[1], np.floor(bottom + 0.5).astype('int32'))
        right = min(image.size[0], np.floor(right + 0.5).astype('int32'))

        bbox = ((left, top), (right, bottom))
        print '************************** BBOX', bbox

        '''if (x2 - x1) * (y2 - y1) < 13500:
            return True'''

        return not check_traffic_light(self.current_frame, bbox)['detected_traffic_stop']

    def image_update_callback(self, data):
        try:
            cv_image = self.bridge.imgmsg_to_cv2(data, "bgr8")
        except CvBridgeError as e:
            raise e
        # cv_image = utils.compressed_imgmsg_to_cv2(data)
        self.current_frame = cv_image

    @staticmethod
    def convert_results_to_message(out_boxes, out_scores, out_classes):

        msgs = DetectionResults()
        for i in range(len(out_scores)):
            msg = DetectionResult()
            msg.out_class = out_classes[i]
            msg.out_score = out_scores[i]
            msg.location = out_boxes[i, :]
            msgs.results.append(msg)

        return msgs
Пример #48
0
class gcsrvclient:
    def __init__(self):

        self.bridge = CvBridge()
        # set ros publishers and subscribers
        self.image_pub = rospy.Publisher("image_topic", Image, queue_size=2)
        self.result_pub = rospy.Publisher("result_topic", String, queue_size=2)
        self.image_sub = rospy.Subscriber("/usb_cam/image_raw",
                                          Image,
                                          self.imageCallback,
                                          queue_size=2)

        # main image variables
        self.image_msg = False
        self.cv_image = False
        self.current_image = False

        # parameters
        self.display_image = True
        self.display_labels = True
        self.update_rate = 1.0

        # control variables
        self.have_image = False
        self.wait_window = True
        self.have_detection = False

        # set next image update for now
        self.next_time = rospy.get_time()

        print "init done"

    def get_image(self):

        # convert to ros image to cv image
        try:
            cv_image = self.bridge.imgmsg_to_cv2(self.current_image, "bgr8")
        except CvBridgeError as e:
            print(e)

        # set image and control variables
        image_message = self.current_image
        self.have_image = False

        return image_message, cv_image

    def get_emos(self, f):
        emos = {k: v for k, v in f.items() if k.endswith('Likelihood')}
        emos = {k: v for k, v in emos.items() if v != 'VERY_UNLIKELY'}
        return emos

    def draw_emos(self, image, f, pos):
        emos = self.get_emos(f)
        if emos:
            for k, v in emos.items():
                t = "%s : %s" % (k, v)
                x = pos[0]
                y = pos[1]
                cv2.putText(image, t, (x, y), cv2.FONT_HERSHEY_SIMPLEX, 0.5,
                            (0, 255, 0), 2)

    def show_detection(self, image, response):
        resp = eval(response)
        #result = resp['responses']
        result = resp['responses'][0]

        if not 'faceAnnotations' in result:
            print "No Face 0"
            return

        for f in result['faceAnnotations']:
            box = [(v['x'], v['y']) for v in f['fdBoundingPoly']['vertices']]
            pts = numpy.array(box, numpy.int32)
            pts = pts.reshape((-1, 1, 2))
            cv2.polylines(image, [pts], True, (0, 255, 0), thickness=2)

            self.draw_emos(image, f, box[1])

    def print_labels(self, response):
        resp = eval(response)
        result = resp['responses'][0]
        print json.dumps(result, indent=2, sort_keys=True)

    def create_service_request(self, img):
        req = gc_srvs.RequestAnnotationsRequest()
        req.image = img
        req.annotations = ['FACE_DETECTION']
        req.max_results = [10]
        return req

    def imageCallback(self, data):
        # filter image for desired rate
        if rospy.get_time() < self.next_time:
            return
        self.next_time = rospy.get_time() + 1.0
        # set image and control variables
        self.current_image = data
        self.have_image = True

    def publish_results(self, response):
        resp = eval(response)
        result = resp['responses'][0]
        self.image_pub.publish(self.image_msg)
        self.result_pub.publish(json.dumps(result, indent=2, sort_keys=True))

    def spin(self):

        if self.have_image:
            # set image for request
            self.image_msg, self.cv_image = self.get_image()

            # request an get results
            req = self.create_service_request(self.image_msg)
            GetAnnotationSrv = rospy.ServiceProxy('get_annotation',
                                                  gc_srvs.RequestAnnotations)
            resp = GetAnnotationSrv(req)

            # output results
            self.print_labels(resp.response)
            self.show_detection(self.cv_image, resp.response)
            self.publish_results(resp.response)

            # show debug window
            if self.display_image:
                cv2.imshow('modified', self.cv_image)

                if self.wait_window:
                    cv2.waitKey(2000)
                else:
                    cv2.waitKey(1)
Пример #49
0
class task1_2(object):
    def __init__(self):

        self.predict_ser = rospy.Service("prediction", task1out,
                                         self.prediction_cb)
        self.cv_bridge = CvBridge()

        # cropped version from https://github.com/pytorch/vision/blob/master/torchvision/models/vgg.py
        self.cfg = {
            'vgg11':
            [64, 'M', 128, 'M', 256, 256, 'M', 512, 512, 'M', 512, 512, 'M'],
            'vgg13': [
                64, 64, 'M', 128, 128, 'M', 256, 256, 'M', 512, 512, 'M', 512,
                512, 'M'
            ],
            'vgg16': [
                64, 64, 'M', 128, 128, 'M', 256, 256, 256, 'M', 512, 512, 512,
                'M', 512, 512, 512, 'M'
            ],
            'vgg19': [
                64, 64, 'M', 128, 128, 'M', 256, 256, 256, 256, 'M', 512, 512,
                512, 512, 'M', 512, 512, 512, 512, 'M'
            ],
        }
        self.means = np.array([
            103.939, 116.779, 123.68
        ]) / 255.  # mean of three channels in the order of BGR
        self.h, self.w = 480, 640
        self.n_class = 4
        model_dir = "/root/sis_mini_competition_2018"  #
        model_name = "sis_99epoch.pkl"
        self.vgg_model = VGGNet(self.cfg, requires_grad=True, remove_fc=True)
        self.fcn_model = FCN16s(pretrained_net=self.vgg_model,
                                n_class=self.n_class)

        use_gpu = torch.cuda.is_available()
        num_gpu = list(range(torch.cuda.device_count()))
        rospy.loginfo("Cuda available: %s", use_gpu)

        if use_gpu:
            ts = time.time()
            self.vgg_model = self.vgg_model.cuda()
            self.fcn_model = self.fcn_model.cuda()
            self.fcn_model = nn.DataParallel(self.fcn_model,
                                             device_ids=num_gpu)
            print("Finish cuda loading, time elapsed {}".format(time.time() -
                                                                ts))
        state_dict = torch.load(os.path.join(model_dir, model_name))
        self.fcn_model.load_state_dict(state_dict)

        self.mask1 = np.zeros((self.h, self.w))
        self.MAXAREA = 18000
        self.MINAREA = 1000
        self.brand = ['doublemint', 'kinder', 'kusan']
        rospy.loginfo("Service ready!")

    def prediction_cb(self, req):
        resp = task1outResponse()
        im_msg = rospy.wait_for_message('/camera/rgb/image_rect_color',
                                        Image,
                                        timeout=None)
        resp.pc = rospy.wait_for_message('/camera/depth_registered/points',
                                         PointCloud2,
                                         timeout=None)
        rospy.loginfo("Get image.")
        resp.org_image = im_msg
        try:
            img = self.cv_bridge.imgmsg_to_cv2(im_msg, "bgr8")
        except CvBridgeError as e:
            print(e)
        origin = img
        img = img[:, :, ::-1]  # switch to BGR

        img = np.transpose(img, (2, 0, 1)) / 255.
        img[0] -= self.means[0]
        img[1] -= self.means[1]
        img[2] -= self.means[2]

        now = rospy.get_time()
        # convert to tensor
        img = img[np.newaxis, :]
        img = torch.from_numpy(img.copy()).float()

        output = self.fcn_model(img)
        output = output.data.cpu().numpy()

        N, _, h, w = output.shape
        mask = output.transpose(0, 2, 3, 1).reshape(
            -1, self.n_class).argmax(axis=1).reshape(N, h, w)[0]
        rospy.loginfo("Predict time : %f", rospy.get_time() - now)
        now = rospy.get_time()

        show_img = np.asarray(origin)
        count = np.zeros(3)
        self.mask1[:, :] = 0
        self.mask1[mask != 0] = 1
        labels = self.adj(self.mask1)
        mask = np.asarray(mask, np.uint8)
        mask2 = np.zeros((h, w))
        rospy.loginfo("f**k 1")
        for i in range(1, self.n_class):
            self.mask1[:, :] = 0
            self.mask1[mask == i] = 1
            self.mask1 = np.asarray(self.mask1, np.uint8)
            self.mask1 = cv2.GaussianBlur(self.mask1, (5, 5), 0)

            cnts = cv2.findContours(self.mask1.copy(), cv2.RETR_CCOMP,
                                    cv2.CHAIN_APPROX_SIMPLE)
            cnts = cnts[1]

            sd = ShapeDetector()
            rospy.loginfo("f**k 2")
            for c in cnts:
                if self.MAXAREA >= cv2.contourArea(c) >= self.MINAREA:
                    rospy.loginfo("f**k 3")
                    shape = sd.detect(c)
                    if shape is "rectangle":
                        M = cv2.moments(c)
                        if M["m00"] == 0:
                            break
                        cX = int(M["m10"] / M["m00"])
                        cY = int(M["m01"] / M["m00"])

                        ry = float(480 - cY) / 600
                        rx = float(cX - 320) * (48 + 0.675 * ry) / 64000
                        rospy.loginfo("(%f,%f)", rx, ry)
                        #######Service for arm########
                        rospy.wait_for_service('arm_planning')
                        try:
                            move_arm = rospy.ServiceProxy(
                                'arm_planning', Move_Arm)
                            move_arm(ry + 0.03, -rx)  #0.141,0.02
                        except rospy.ServiceException, e:
                            print "Service call failed: %s" % e
                        ##############################
                        rect = cv2.minAreaRect(c)
                        box = cv2.boxPoints(rect)
                        box = np.int0(box)

                        cv2.drawContours(show_img, [box], 0, (255, 0, 0), 2)
                        cv2.putText(show_img, self.brand[i - 1], (cX, cY),
                                    cv2.FONT_HERSHEY_SIMPLEX, 0.8, (0, 0, 0),
                                    2)
                        #_, labels = cv2.conectedComponents(mask)
                        p = labels[c[0, 0, 1], c[0, 0, 0]]
                        mask2[labels == p] = i
                        count[i - 1] += 1
        rospy.loginfo("Image processing time : %f", rospy.get_time() - now)
        #cv2.imshow('My image', show_img)
        cv2.imwrite("/hosthome/test.jpg", show_img)
        resp.process_image = self.cv_bridge.cv2_to_imgmsg(show_img, "bgr8")
        resp.mask = self.cv_bridge.cv2_to_imgmsg(mask2, "64FC1")
        print(count)

        return resp
Пример #50
0
class TLDetector(object):
    def __init__(self):
        rospy.init_node('tl_detector')

        self.pose = None
        self.base_waypoints = None
        self.camera_image = None
        self.lights = []
        self.stopline_waypoints = []
        self.has_image = False

        # We thank John Chen's mentioning of this apprach in the slack channel #s_p-system-integrat
        self.path = rospy.get_param('~model_path')
        self.camera_topic = rospy.get_param('~camera_topic')
        ####

        self.sub1 = rospy.Subscriber('/current_pose', PoseStamped, self.pose_cb)
        self.sub2 = rospy.Subscriber('/base_waypoints', Lane, self.waypoints_cb)

        '''
        /vehicle/traffic_lights provides you with the location of the traffic light in 3D map space and
        helps you acquire an accurate ground truth data source for the traffic light
        classifier by sending the current color state of all traffic lights in the
        simulator. When testing on the vehicle, the color state will not be available. You'll need to
        rely on the position of the light and the camera image to predict it.
        '''

        self.sub3 = rospy.Subscriber('/vehicle/traffic_lights', TrafficLightArray, self.traffic_cb)
        self.sub6 = rospy.Subscriber(self.camera_topic, Image, self.image_cb)

        config_string = rospy.get_param("/traffic_light_config")
        self.config = yaml.load(config_string)

        self.upcoming_light_pub = rospy.Publisher('/traffic_waypoint', Int32, queue_size=1)

        self.bridge = CvBridge()
        self.light_classifier = TLClassifier(self.path)
        self.listener = tf.TransformListener()

        self.state = TrafficLight.UNKNOWN

        self.last_wp = -1
        self.state_count = 0

        # constrain the rate at which this node is processed to specified rate; ros::spin() would add unnecessary
        # overhead given this node's purpose (see below)
        # https://stackoverflow.com/questions/40508651/writing-a-ros-node-with-both-a-publisher-and-subscriber
        self.updateRate = 10
        self.loop()

    def loop(self):
        rate = rospy.Rate(self.updateRate)
        while not rospy.is_shutdown():

            # if following condtions met all required subcription callback functions have run
            if self.pose and self.base_waypoints and self.has_image:
                light_wp, state = self.process_traffic_lights()
                '''
                Publish upcoming red lights at camera frequency.
                Each predicted state has to occur `STATE_COUNT_THRESHOLD` number
                of times till we start using it. Otherwise the previous stable state is
                used.
                '''
                if self.state != state:
                    self.state_count = 0
                    self.state = state
                elif self.state_count >= STATE_COUNT_THRESHOLD:
                    # distinguish among cases (publish (-) values if GREEN or UNKNOWN)
                    if state == TrafficLight.GREEN or state == TrafficLight.UNKNOWN:
                        light_wp = -1

                    self.last_wp = light_wp
                    self.upcoming_light_pub.publish(Int32(light_wp))
                    # for debug
                    print ("tl_detector state: ", Int32(light_wp))
                    print ("tl_detector state: ", state)
                    print ("tl_detector state: ", Int32(light_wp))
                    print ("tl_detector state: ", state)

                else:
                    self.upcoming_light_pub.publish(Int32(self.last_wp))

                self.state_count += 1

            rate.sleep()

    def pose_cb(self, msg):
        self.pose = msg

    def waypoints_cb(self, msg):
        if self.base_waypoints is None:
            self.base_waypoints = []
            for wp in msg.waypoints:
                self.base_waypoints.append(wp)

        # only do this once since these values don't change
        self.sub2.unregister()
        rospy.loginfo('base_waypoints sub unregistered')

        # initilize waypoints at which the car must stop if the light is red
        self.initialize_stop_positions()

    def traffic_cb(self, msg):
        self.lights = msg.lights

    def image_cb(self, msg):
        """ Interface with ROS to receive image 

        Args:
            msg (Image): image from car-mounted camera

        """
        rospy.logwarn('image received by tl_detector node')
        self.has_image = True
        self.camera_image = msg

    # Used for stop position waypoints
    def create_pose_vector(self, x, y, z):
        wp = PoseStamped()
        wp.pose.position.x = x
        wp.pose.position.y = y
        wp.pose.position.z = z
        return wp

    def initialize_stop_positions(self):
        # Returns waypoint indexes for each stop position
        # List of positions that correspond to the line to stop in front of at a given intersection
        stop_line_positions = self.config['stop_line_positions']

        for i in range(len(stop_line_positions)):
            temp = self.create_pose_vector(stop_line_positions[i][0], stop_line_positions[i][1], 0)
            index = self.get_closest_waypoint(temp.pose, self.base_waypoints, 1e10)
            self.stopline_waypoints.append(index)

    def get_pose_vector(self, pose):
        return np.asarray([pose.position.x, pose.position.y, pose.position.z], np.float32)

    def get_closest_waypoint(self, pose, waypoints, dist):
        """Identifies the index of the given position within waypoints if less than specified distance 
            https://en.wikipedia.org/wiki/Closest_pair_of_points_problem
        Args:
            pose (Pose): position to match a waypoint to
            waypoints: ordered list of waypoints (either track waypoints or traffic lights waypoints)
            dist: only for positions w/ distances less than this value

        """
        # TODO implement

        index = None
        for i, loc in enumerate(waypoints):
            a = self.get_pose_vector(pose)
            b = self.get_pose_vector(loc.pose.pose)
            temp = np.linalg.norm(a - b)
            if dist > temp:
                dist = temp
                index = i

        return index

    def get_light_state(self):
        """Determines the current color of the traffic light

        Args:
            light (TrafficLight): light to classify

        Returns:
            int: ID of traffic light color (specified in styx_msgs/TrafficLight)

        """
        if (not self.has_image):
            return False

        # We thank John Chen's mentioning of this apprach in the slack channel #s_p-system-integrat:
        # fixing convoluted camera encoding...
        if hasattr(self.camera_image, 'encoding'):
            self.attribute = self.camera_image.encoding
            if self.camera_image.encoding == '8UC3':
                self.camera_image.encoding = "rgb8"
        else:
            self.camera_image.encoding = 'rgb8'
        ####

        cv_image = self.bridge.imgmsg_to_cv2(self.camera_image, "rgb8")

        # Get classification
        classification = self.light_classifier.get_classification(cv_image)

        return classification

    def process_traffic_lights(self):
        """Finds closest visible traffic light, if one exists, and determines its
            location and color

        Returns:
            int: index of waypoint closes to the upcoming stop line for a traffic light (-1 if none exists)
            int: ID of traffic light color (specified in styx_msgs/TrafficLight)

        """

        # TODO find the closest visible traffic light (if one exists)
        # ***only check for lights within 100 meters***#
        tl_index = self.get_closest_waypoint(self.pose.pose, self.lights, 100)

        if tl_index is not None:
            light_wp = self.get_closest_waypoint(self.lights[tl_index].pose.pose, self.base_waypoints, 1e10)
            waypoints_greater = [i for i, v in enumerate(self.stopline_waypoints) if v > light_wp]
            if len(waypoints_greater) > 0:
                first_greater_than = waypoints_greater[0]
            else:
                first_greater_than = len(self.stopline_waypoints)
            state = self.get_light_state()
            return self.stopline_waypoints[first_greater_than - 1], state
        else:
            return -1, TrafficLight.UNKNOWN
class dvrkGraspingDetection(threading.Thread):
    def __init__(self, interval_ms=10, video_recording=False):
        # data members
        self.__bridge = CvBridge()
        self.__img_raw_left = []
        self.__img_raw_right = []
        self.__actuator_current_measured_PSM1 = []
        self.__actuator_current_measured_PSM2 = []
        self.__state_jaw_current_PSM1 = []
        self.__state_jaw_current_PSM2 = []

        # threading
        threading.Thread.__init__(self)
        self.__interval_ms = interval_ms
        self.__stop_flag = False

        # subscriber
        self.__sub_list = [
            rospy.Subscriber('/endoscope/left/image_raw/compressed',
                             CompressedImage, self.__img_raw_left_cb),
            rospy.Subscriber('/endoscope/right/image_raw/compressed',
                             CompressedImage, self.__img_raw_right_cb),
            rospy.Subscriber('/dvrk/PSM1/io/actuator_current_measured',
                             JointState,
                             self.__actuator_current_measured_PSM1_cb),
            rospy.Subscriber('/dvrk/PSM2/io/actuator_current_measured',
                             JointState,
                             self.__actuator_current_measured_PSM2_cb),
            rospy.Subscriber('/dvrk/PSM1/state_jaw_current', JointState,
                             self.__state_jaw_current_PSM1_cb),
            rospy.Subscriber('/dvrk/PSM2/state_jaw_current', JointState,
                             self.__state_jaw_current_PSM2_cb)
        ]

        # create node
        if not rospy.get_node_uri():
            rospy.init_node('detect_grasping_node',
                            anonymous=True,
                            log_level=rospy.WARN)
            self.rate = rospy.Rate(1000.0 / self.__interval_ms)
        else:
            rospy.logdebug(rospy.get_caller_id() +
                           ' -> ROS already initialized')

        # video recording
        self.__video_recording = video_recording
        if self.__video_recording is True:
            fps = 1000.0 / self.__interval_ms
            fcc = cv2.VideoWriter_fourcc('D', 'I', 'V', 'X')
            self.__img_width = 640
            self.__img_height = 360
            self.out = cv2.VideoWriter('video_recorded.avi', fcc, fps,
                                       (self.__img_width, self.__img_height))
            print("start recording")

        # initializing variables
        self.__jaw1_curr_PSM1_prev = 0
        self.__jaw2_curr_PSM1_prev = 0
        self.__jaw1_curr_PSM2_prev = 0
        self.__jaw2_curr_PSM2_prev = 0

        self.start()
        rospy.spin()

    def start(self):
        self.__stop_flag = False
        self.__thread = threading.Thread(target=self.run,
                                         args=(lambda: self.__stop_flag, ))
        self.__thread.daemon = True
        self.__thread.start()

    def stop(self):
        self.__stop_flag = True

    def run(self, stop):
        while True:
            # Resizing images
            img1 = cv2.resize(self.__img_raw_left,
                              (self.__img_width, self.__img_height))
            img2 = cv2.resize(self.__img_raw_right,
                              (self.__img_width, self.__img_height))

            # Low pass filtering
            fc = 1  # (Hz)
            dt = 0.01  # (ms)
            jaw1_curr_PSM1 = U.LPF(self.__actuator_current_measured_PSM1[5],
                                   self.__jaw1_curr_PSM1_prev, fc, dt)
            self.__jaw1_curr_PSM1_prev = jaw1_curr_PSM1
            jaw2_curr_PSM1 = U.LPF(self.__actuator_current_measured_PSM1[6],
                                   self.__jaw2_curr_PSM1_prev, fc, dt)
            self.__jaw2_curr_PSM1_prev = jaw2_curr_PSM1
            jaw1_curr_PSM2 = U.LPF(self.__actuator_current_measured_PSM2[5],
                                   self.__jaw1_curr_PSM2_prev, fc, dt)
            self.__jaw1_curr_PSM2_prev = jaw1_curr_PSM2
            jaw2_curr_PSM2 = U.LPF(self.__actuator_current_measured_PSM2[6],
                                   self.__jaw2_curr_PSM2_prev, fc, dt)
            self.__jaw2_curr_PSM2_prev = jaw2_curr_PSM2

            # Current thresholding
            self.__threshold_PSM1 = 0.3  # (A)
            self.__threshold_PSM2 = 0.25  # (A)
            if self.__state_jaw_current_PSM1[0] <= 0:
                if jaw1_curr_PSM1 - jaw2_curr_PSM1 > self.__threshold_PSM1:
                    cv2.circle(img1, (540, 300), 30, (0, 255, 0), -1)
                else:
                    cv2.circle(img1, (540, 300), 30, (0, 0, 255), -1)
            else:
                cv2.circle(img1, (540, 300), 30, (0, 0, 255), -1)

            if self.__state_jaw_current_PSM2[0] <= 0:
                if jaw1_curr_PSM2 - jaw2_curr_PSM2 > self.__threshold_PSM2:
                    cv2.circle(img1, (100, 300), 30, (0, 255, 0), -1)
                else:
                    cv2.circle(img1, (100, 300), 30, (0, 0, 255), -1)
            else:
                cv2.circle(img1, (100, 300), 30, (0, 0, 255), -1)

            cv2.imshow("original1", img1)

            if self.__video_recording is True:
                self.out.write(img1)
            self.rate.sleep()

            if cv2.waitKey(1) & 0xFF == ord('q'):
                if self.__video_recording is True:
                    print("finishing recording")
                    self.out.release()
                cv2.destroyAllWindows()
                stop()
                break

    def __img_raw_left_cb(self, data):
        try:
            if type(data).__name__ == 'CompressedImage':
                self.__img_raw_left = self.__compressedimg2cv2(data)
            elif type(data).__name__ == 'Image':
                self.__img_raw_left = self.__bridge.imgmsg_to_cv2(data, "bgr8")
        except CvBridgeError as e:
            print(e)

    def __img_raw_right_cb(self, data):
        try:
            if type(data).__name__ == 'CompressedImage':
                self.__img_raw_right = self.__compressedimg2cv2(data)
            elif type(data).__name__ == 'Image':
                self.__img_raw_right = self.__bridge.imgmsg_to_cv2(
                    data, "bgr8")
        except CvBridgeError as e:
            print(e)

    def __compressedimg2cv2(self, comp_data):
        np_arr = np.fromstring(comp_data.data, np.uint8)
        return cv2.imdecode(np_arr, cv2.IMREAD_COLOR)

    def __actuator_current_measured_PSM1_cb(self, data):
        joint = np.array(0, dtype=np.float)
        joint.resize(len(data.position))
        joint.flat[:] = data.position
        self.__actuator_current_measured_PSM1 = list(joint)

    def __actuator_current_measured_PSM2_cb(self, data):
        joint = np.array(0, dtype=np.float)
        joint.resize(len(data.position))
        joint.flat[:] = data.position
        self.__actuator_current_measured_PSM2 = list(joint)

    def __state_jaw_current_PSM1_cb(self, data):
        joint = np.array(0, dtype=np.float)
        joint.resize(len(data.position))
        joint.flat[:] = data.position
        self.__state_jaw_current_PSM1 = list(joint)

    def __state_jaw_current_PSM2_cb(self, data):
        joint = np.array(0, dtype=np.float)
        joint.resize(len(data.position))
        joint.flat[:] = data.position
        self.__state_jaw_current_PSM2 = list(joint)
Пример #52
0
class following_final():
	# Distance in mm
	invalid_thresh = 300
	desired_thresh = 1000
	desired_lowBound = 950
	desired_upBound = 1050
	invalid_max = 2000
	max_speed = 1


	def __init__(self):
		rospy.init_node('image_converter', anonymous=True)
		# Initialize bridge
		self.bridge = CvBridge()
		# Subscribe to depth sensor and get raw image
		self.depth_sub = rospy.Subscriber("/camera/depth/image_raw",Image,self.callback)
		#self.depth_sub = rospy.Subscriber("/camera/depth_registered/image_raw",Image,self.callback_depth)
		# Publish to navigation to move robot
		self.cmd_vel = rospy.Publisher('cmd_vel_mux/input/navi', Twist, queue_size=10)
		# Initialize Twist that will be published to cmd_vel
		self.move_cmd = Twist()

		self.r = rospy.Rate(10)

	def callback(self,data):
		try:
			
			# Gain Values for movement

			# X gain rotation
			K = 0.0035
			# Kx is for movment in z direction forward backwards
			Kx = .0005

			# Get Image and find size of image
			self.depth_image = self.bridge.imgmsg_to_cv2(data, "passthrough")
			rows, col, channels = self.depth_image.shape #grey scale channel is 1, rgb is 3

			# Find Center of Image
			cR = np.int(np.round(rows/2))
			cC = np.int(np.round(col/2))

			# How Large our field of view for our desired object i.e where we looking in the picture for our object
			# Mask to remove any uneccesary information outside our looking area.
			rowFrac = np.int(np.round(.25*cR))
			colFrac = np.int(np.round(.4*cC))

			#Masks the quadrant it is interested on (default = upper center)
			self.mask2 =  np.zeros((rows,col))
			self.mask2[cR+rowFrac:cR+(2*rowFrac),cC-colFrac:cC+colFrac] = 5
			self.mask2 = np.uint16(self.mask2)
			self.mask2 = cv2.inRange(self.mask2,np.array(4,dtype = "uint16"),np.array(6,dtype = "uint16"))

			# Mask to get values of specific box in z direction only interested in our object/person
			min_z= np.array(500, dtype = "uint16") #bgr
			max_z= np.array(2000, dtype = "uint16")
			self.mask = cv2.inRange(self.depth_image, min_z, max_z)
			
			#Combination of masks
			self.mask3 = cv2.bitwise_and(self.mask,self.mask, mask= self.mask2)
			image = cv2.bitwise_and(self.depth_image,self.depth_image, mask= self.mask3)

			#Remove unnecesarry values
			image = image.astype(float)
			image[image==0] = np.nan
			image = image[~np.isnan(image)]

			# Get moment/centroid of object
			M = cv2.moments(self.mask3)

			# Calculate center of object and find error from center object
			# Centroid not found
			if (M['m00'] == 0):
				rospy.loginfo('Not tracking ')
				self.move_cmd.linear.x = 0
				self.move_cmd.angular.z = 0

			#Centroid found:
			if ( M['m00'] > 0):
				cx = int(M['m10']/M['m00'])
				cy = int(M['m01']/M['m00'])
				centerOfObject = (int(cx),int(cy))
				dx = cx - col/2 # +ve move left, -ve move right?
				dy = cy - rows/2
				depth = np.median(image)
				rospy.loginfo('depth is '+ str(depth))

				#dz range can go from 1100
				dz = depth - self.desired_thresh

				#Ignore very low depth values
				if depth <= self.invalid_thresh:
					self.move_cmd.linear.x = 0
					self.move_cmd.angular.z = K*(0)*dx

				#If below low bound but higher than invalid then move backwards?
				elif depth < self.desired_lowBound:
					if (abs(Kx*dz) < self.max_speed):
						self.move_cmd.linear.x = Kx*dz
					else:
						self.move_cmd.linear.x = -self.max_speed

					self.move_cmd.angular.z = K*(-1)*dx

				#If below upper bound but higher than low bound dont move forward but do rotate
				elif depth < self.desired_upBound:
					self.move_cmd.linear.x = 0*Kx
					self.move_cmd.angular.z = K*(-1)*dx

				#If below the invalid thresh then move forward
				elif depth < self.invalid_max:
					if (Kx*dz < self.max_speed):
						self.move_cmd.linear.x = Kx*dz
					else:
						self.move_cmd.linear.x = -self.max_speed

					self.move_cmd.angular.z = K*(-1)*dx

				#If above threshold do nothing
				elif depth >= self.invalid_max:
					self.move_cmd.linear.x = 0
					self.move_cmd.angular.z = K*(0)*dx
				else:
					self.move_cmd.linear.x = 0
					self.move_cmd.angular.z = K*(0)*dx
				

			self.cmd_vel.publish(self.move_cmd)

			self.r.sleep()


		except CvBridgeError, e:
			print e
Пример #53
0
class TLDetector(object):
    def __init__(self):
        rospy.init_node('tl_detector')

        self.pose = None
        self.waypoints = None
        self.waypoints_2d = None
        self.waypoints_tree = None
        self.camera_image = None
        self.lights = []

        sub1 = rospy.Subscriber('/current_pose', PoseStamped, self.pose_cb)
        sub2 = rospy.Subscriber('/base_waypoints', Lane, self.waypoints_cb)
        '''
        /vehicle/traffic_lights provides you with the location of the traffic light in 3D map space and
        helps you acquire an accurate ground truth data source for the traffic light
        classifier by sending the current color state of all traffic lights in the
        simulator. When testing on the vehicle, the color state will not be available. You'll need to
        rely on the position of the light and the camera image to predict it.
        '''
        sub3 = rospy.Subscriber('/vehicle/traffic_lights', TrafficLightArray,
                                self.traffic_cb)
        sub6 = rospy.Subscriber('/image_color', Image, self.image_cb)

        config_string = rospy.get_param("/traffic_light_config")
        self.config = yaml.load(config_string)

        self.upcoming_red_light_pub = rospy.Publisher('/traffic_waypoint',
                                                      Int32,
                                                      queue_size=1)

        self.bridge = CvBridge()
        self.light_classifier = TLClassifier()
        self.listener = tf.TransformListener()

        self.state = TrafficLight.UNKNOWN
        self.last_state = TrafficLight.UNKNOWN
        self.last_wp = -1
        self.state_count = 0

        rospy.spin()

    def pose_cb(self, msg):
        self.pose = msg

    def waypoints_cb(self, waypoints):
        self.waypoints = waypoints
        if not self.waypoints_2d:
            self.waypoints_2d = [[
                waypoint.pose.pose.position.x, waypoint.pose.pose.position.y
            ] for waypoint in waypoints.waypoints]
            self.waypoints_tree = KDTree(self.waypoints_2d)

    def traffic_cb(self, msg):
        self.lights = msg.lights

    def image_cb(self, msg):
        """Identifies red lights in the incoming camera image and publishes the index
            of the waypoint closest to the red light's stop line to /traffic_waypoint

        Args:
            msg (Image): image from car-mounted camera

        """
        self.has_image = True
        self.camera_image = msg
        light_wp, state = self.process_traffic_lights()
        '''
        Publish upcoming red lights at camera frequency.
        Each predicted state has to occur `STATE_COUNT_THRESHOLD` number
        of times till we start using it. Otherwise the previous stable state is
        used.
        '''
        if self.state != state:
            self.state_count = 0
            self.state = state
        elif self.state_count >= STATE_COUNT_THRESHOLD:
            self.last_state = self.state
            light_wp = light_wp if state == TrafficLight.RED or state == TrafficLight.YELLOW else -1
            self.last_wp = light_wp
            self.upcoming_red_light_pub.publish(Int32(light_wp))
        else:
            self.upcoming_red_light_pub.publish(Int32(self.last_wp))
        self.state_count += 1

    def get_closest_waypoint(self, x, y):
        """Identifies the closest path waypoint to the given position
            https://en.wikipedia.org/wiki/Closest_pair_of_points_problem
        Args:
            pose (Pose): position to match a waypoint to

        Returns:
            int: index of the closest waypoint in self.waypoints

        """
        #TODO implement
        closest_idx = self.waypoints_tree.query([x, y])[1]

        return closest_idx

    def get_light_state(self, light):
        """Determines the current color of the traffic light

        Args:
            light (TrafficLight): light to classify

        Returns:
            int: ID of traffic light color (specified in styx_msgs/TrafficLight)

        """
        """
        stop_line_positions = self.config['stop_line_positions']
        if(self.pose):
            car_position = self.get_closest_waypoint(self.pose.pose.position.x, self.pose.pose.position.y)
	nbr_wp = len(self.waypoints.waypoints)
        diff = nbr_wp
        for i, temp_light in enumerate(self.lights):
	    #Get stop line waypoint index
	    line = stop_line_positions[i]
	    temp_wp = self.get_closest_waypoint(line[0], line[1])
	    # Find closest stop line
            dist = temp_wp - car_position
	    dist_next_tour = temp_wp + nbr_wp - car_position
	    if dist >= 0 and dist < diff:
	        diff = dist
        	light = temp_light
	        light_wp = temp_wp
	    if dist_next_tour >= 0 and dist_next_tour < diff:
	        diff = dist_next_tour
     	        light = temp_light
		light_wp = temp_wp

        # for getting image
        time = rospy.get_time()
	cv_image = self.bridge.imgmsg_to_cv2(self.camera_image, "bgr8")
	state = light.state
        if diff > 92:
	    state = 4
	name = '{}_{}.png'.format(time, state)
	path = '/capstone/data/imgs/'
	filename = path + name
	rospy.logwarn('%s dist: %s', filename, diff)
	cv2.imwrite(filename, cv_image)
	"""
        # Just for debugging
        #return light.state

        if (not self.has_image):
            self.prev_light_loc = None
            return False

        cv_image = self.bridge.imgmsg_to_cv2(self.camera_image, "bgr8")

        #Get classification
        return self.light_classifier.get_classification(cv_image)

    def process_traffic_lights(self):
        """Finds closest visible traffic light, if one exists, and determines its
            location and color

        Returns:
            int: index of waypoint closes to the upcoming stop line for a traffic light (-1 if none exists)
            int: ID of traffic light color (specified in styx_msgs/TrafficLight)

        """
        light = None

        # List of positions that correspond to the line to stop in front of for a given intersection
        stop_line_positions = self.config['stop_line_positions']
        if (self.pose):
            car_position = self.get_closest_waypoint(self.pose.pose.position.x,
                                                     self.pose.pose.position.y)

            #TODO find the closest visible traffic light (if one exists)
            diff = 500
            for i, temp_light in enumerate(self.lights):
                #Get stop line waypoint index
                line = stop_line_positions[i]
                temp_wp = self.get_closest_waypoint(line[0], line[1])
                # Find closest stop line
                dist = temp_wp - car_position
                if dist >= 0 and dist < diff:
                    diff = dist
                    light = temp_light
                    light_wp = temp_wp

        if light:
            state = self.get_light_state(light)
            return light_wp, state

        return -1, TrafficLight.UNKNOWN
Пример #54
0
class TLDetector(object):
    def __init__(self):
        rospy.init_node('tl_detector')

        self.pose = None
        self.waypoints = None
        self.camera_image = None
        self.lights = []
        self.tl_wps = []

        sub1 = rospy.Subscriber('/current_pose', PoseStamped, self.pose_cb)
        sub2 = rospy.Subscriber('/base_waypoints', Lane, self.waypoints_cb)

        '''
        /vehicle/traffic_lights provides you with the location of the traffic light in 3D map space and
        helps you acquire an accurate ground truth data source for the traffic light
        classifier by sending the current color state of all traffic lights in the
        simulator. When testing on the vehicle, the color state will not be available. You'll need to
        rely on the position of the light and the camera image to predict it.
        '''
        sub3 = rospy.Subscriber('/vehicle/traffic_lights', TrafficLightArray, self.traffic_cb)
        sub6 = rospy.Subscriber('/image_color', Image, self.image_cb)

        config_string = rospy.get_param("/traffic_light_config")
        rospy.logwarn("The parameter string is : %s", config_string )
        self.config = yaml.load(config_string)

        self.upcoming_light_pub = rospy.Publisher('/traffic_waypoint', Int32, queue_size=1)
        
        # debug: publisher of cross-correlation results
        self.ccresult_pub = rospy.Publisher('/traffic_ccresult', Image, queue_size=1)
        
                
        
        self.bridge = CvBridge()
        self.light_classifier = TLClassifier()
        self.listener = tf.TransformListener()

        self.state = TrafficLight.UNKNOWN
        self.last_state = TrafficLight.UNKNOWN
        self.last_wp = -1
        self.state_count = 0
        self.count = 0
        self.camera_car_position = []
       
        
        # x-margin is the margin in pixels that corrspondes to a
        # 5 meter distance from the traffic light along the y-axis (x in image).
        # we use this margin to search for the red pixels instead of a fixed one        
        self.x_margin = 50 # default is 50 (Yuda)
        
        # dimensions of the red-light template in pixels
        self.template_x = 30 # (pixels in x) just a wild-guess for initial value. 
        self.template_y = 30 # (pixels in y)
        # the actual dimension of a single light as a swuare         
        self.TrafficLight_dim = 1.6# (suppose to be in meters but scaling is a bit hand-tuned) 
        
        
        rospy.spin()

    def pose_cb(self, msg):
        self.pose = msg

    def waypoints_cb(self, waypoints):
        self.waypoints = waypoints
       
    def traffic_cb(self, msg):
        self.lights = msg.lights

    def image_cb(self, msg):
        """Identifies red lights in the incoming camera image and publishes the index
            of the waypoint closest to the red light's stop line to /traffic_waypoint

        Args:
            msg (Image): image from car-mounted camera

        """
        self.has_image = True
        self.camera_image = msg
#        self.camera_car_position.append(self.pose.pose.position)
#        if len(self.camera_car_position) > DELAY:
#            self.camera_car_position.pop(0)
        light_wp, state = self.process_traffic_lights()

        '''
        Publish upcoming red lights at camera frequency.
        Each predicted state has to occur `STATE_COUNT_THRESHOLD` number
        of times till we start using it. Otherwise the previous stable state is
        used.
        '''
        if self.state != state:
            self.state_count = 0
            self.state = state
        elif self.state_count >= STATE_COUNT_THRESHOLD:
            self.last_state = self.state
            if state == TrafficLight.UNKNOWN:        
                self.upcoming_light_pub.publish(Int32(-1))
                return
            self.last_wp = light_wp
            self.upcoming_light_pub.publish(Int32( light_wp | (self.state << 16) ))
        else:
            self.upcoming_light_pub.publish(Int32(self.last_wp | (self.last_state << 16) ))
        self.state_count += 1

    def get_closest_waypoint(self, pose):
        """Identifies the closest path waypoint to the given position
            https://en.wikipedia.org/wiki/Closest_pair_of_points_problem
        Args:
            pose (Pose): position to match a waypoint to

        Returns:
            int: index of the closest waypoint in self.waypoints

        """
        #TODO implement
        closest_index = -1
        closest_dis = -1

        if self.waypoints is not None:
            wps = self.waypoints.waypoints
            for i in range(len(wps)):
                dis = (wps[i].pose.pose.position.x - pose.x) ** 2 + \
                    (wps[i].pose.pose.position.y - pose.y) ** 2

                if (closest_dis == -1) or (closest_dis > dis):
                    closest_dis = dis
                    closest_index = i
        return closest_index


    # George: Here's my version of project_to_image_plane
    #     I am avoiding the TransformListener object as I am not sure about how
    #     to configure it without having doubts. The transform is easy to 
    #     work-out directly from the pose vector and gives me control over the 
    #     coordinate frame.
    def project_to_image_plane(self, point_in_world):
        """Project point from 3D world coordinates to 2D camera image location

        Args:
            point_in_world (Point): 3D location of a point in the world

        Returns:
            x (int): x coordinate of target point in image
            y (int): y coordinate of target point in image

        """
        # Retreving camera intronsics
        fx = self.config['camera_info']['focal_length_x']
        fy = self.config['camera_info']['focal_length_y']
        # image size        
        image_width = self.config['camera_info']['image_width']
        image_height = self.config['camera_info']['image_height']

        # caching the world coordinates of the point
        Px = point_in_world.x
        Py = point_in_world.y
        Pz = point_in_world.z

        # Using the pose to obatin the camera frame as rotation matrix R and 
        # a world position p (NOTEL ASSUMING THAT THE CAMERA COINCIDES WITH 
        # THE CAR'S BARYCENTER 
#        Cx = self.camera_car_position[0].x
#        Cy = self.camera_car_position[0].y
#        Cz = self.camera_car_position[0].z
        Cx = self.pose.pose.position.x
        Cy = self.pose.pose.position.y
        Cz = self.pose.pose.position.z
        
        # print(Px, Py, Pz)
        # print(Cx, Cy, Cz)
        # print('=========')
        
        # get orientation (just the scalar part of the the quaternion)
        s = self.pose.pose.orientation.w # quaternion scalar
        
        # now obtaining orientation of the car (assuming rotation about z: [0;0;1])
        theta = 2 * np.arccos(s)
        # Constraining the angle in [-pi, pi)
        if theta > np.pi:
            theta = -(2 * np.pi - theta)

        # transforming the world point to the camera frame as:
        #
        #               Pc = R' * (Pw - C)

        #        where R' = [ cos(theta)  sin(theta)   0; 
        #                   -sin(theta)  cos(theta)   0;
        #                      0              0      1]
        #
        # Thus,
        p_camera = [ np.cos(theta) * (Px - Cx) + np.sin(theta) * (Py - Cy) , \
                     -np.sin(theta) * (Px - Cx) + np.cos(theta) * (Py - Cy) , \
                     Pz - Cz]
        # print(p_camera)                                                        


        # NOTE: From the simulator, it appears from the change in the angle 
        # that the positive direction of rotation is counter-clockwise. This 
        # means that there are two possible frame arrangements:
        #
        # a) A RIGHT-HAND frame: In this frame, z - points upwards (oposite to the 
        # image y axis)and y points to the left (oposite to the image x-axis)
        #
        # b) A LEFT_HAND frame: In this frame, z-points downwards (same as the
        #    image y-axis) and y points left (oposite to the image x-axis).
        #
        # thus, there are two ways of obtaining the image projection:
        
        
        # =============== Udacity Forums ====================================
        # see https://discussions.udacity.com/t/focal-length-wrong/358568
#        if fx < 10:
#            fx = 2574
#            fy = 2744
#            p_camera[2] -= 1.0  # to account for the elevation of the camera
#            c_x = image_width/2 - 30
#            c_y = image_height + 50
#        x = int(-fx * p_camera[1] / p_camera[0] + c_x)
#        y = int(-fy * p_camera[2] / p_camera[0] + c_y)
         # ===================================================================        
        
        
        # =============== Using actual (given) intrinsics ================
        if fx < 3 or fy < 3: 
            # This means that intrinsics have been normalized
            # so that they can be applied at any resolution                         
            fx = fx * image_width
            fy = fy * image_height
            # MAYBE, assume that camera is 1 m above the ground (not used)
            #p_camera[2] -= 1                       
        # Since we dont know the intersection of the optical axis with the image,
        # we assume it lies in the middle of it. It should work roughly....
        c_x = image_width / 2
        c_y = image_height / 2
        
        x = int(-fx * p_camera[1] / p_camera[0] + c_x)
        y = int(+fy * p_camera[2] / p_camera[0] + c_y)
        # ===============================================================

        # Set the ADAPTIVE search margin for the traffic light.
        self.x_margin = int(np.abs(6 * fx / p_camera[0])) # note the 5 metert factor
        #rospy.logwarn("X-Margin : %i", self.x_margin)
        if (self.x_margin < 20):
            self.x_margin = 20 # use default 20 pixels if too small margin
        if (self.x_margin > 200): # use maximum margin 200 pixels (just to avoid large roi images when out of range)
            self.x_margin = 200 
        
        # Now working out the size (dimension) of the traffic light 
        # (NOTE: ONLY a single light - i.e. on of the three) in pixels
        self.template_x = int( fx * self.TrafficLight_dim / p_camera[0] )
        if (self.template_x > 45 ):
            self.template_x = 45
            
        self.template_y = int( fy * self.TrafficLight_dim / p_camera[0] )
        if (self.template_y > 45 ):
            self.template_y = 45
        

        return (x,y)

    def in_image(self, x, y):
        if x is None or y is None:
            return False
        if x < 0 or x >= self.config['camera_info']['image_width']:
            return False
        if y < 0 or y >= self.config['camera_info']['image_height']:
            return False
        return True

    def get_light_state(self, light):
        """Determines the current color of the traffic light

        Args:
            light (TrafficLight): light to classify

        Returns:
            int: ID of traffic light color (specified in styx_msgs/TrafficLight)

        """
        if(not self.has_image):
            self.prev_light_loc = None
            return False

        cv_image = self.bridge.imgmsg_to_cv2(self.camera_image, "bgr8")

        x, y = self.project_to_image_plane(light.pose.pose.position)

        #TODO use light location to zoom in on traffic light in image
        image_width = self.config['camera_info']['image_width']
        image_height = self.config['camera_info']['image_height']

        # Actually this range is enough. 
        # But we just use a bigger rectangle to make sure the light is in this region
        # ret = cv2.rectangle(cv_image, (x-20,y-50), (x+20,y+50), (0, 0, 255))
        #left = x - 50
        left = x - self.x_margin        
        #right = x + 50
        right = x + self.x_margin        
        top = 20
        bottom = y + 100
        
        state = TrafficLight.UNKNOWN
              
        #if self.in_image(left, top) and self.in_image(right, bottom):
        roi = cv_image[top:bottom, left:right]
        # skip if roi not set (it may happen, despite the in_image tests)
        # NOTE: This 
        if (roi is None): 
            rospy.logwarn("ROI image is None!")
            return state
        # skip if roi is singular (i.e. single row or column)
        if (roi.shape[0] < 2 or roi.shape[1] < 2):
            return state
        # bridge will be useful publishing the classification results  
        bridge = CvBridge()
            
            
        if (self.template_x > 5) and (self.template_y):
            (ccres, state) = self.light_classifier.matchRedTemplate(cv_image, self.template_x, self.template_y)                    
            # publish the results
            if not (ccres is None):                
                self.ccresult_pub.publish(bridge.cv2_to_imgmsg(ccres, "bgr8"))
            
            
        self.count += 1
        # perform light state classification
        #state = self.light_classifier.get_classification(roi)
        #rospy.logwarn("TL state classified: %d, state count %d", state, self.state_count)
        # debug only
        # if self.count > STATE_COUNT_THRESHOLD and self.count < 10: # save some imgs, not all 
        #     cv2.imwrite('/home/student/Tests/imgs/' + ("%.3d-%d" % (self.count, state)) + '.jpg', roi)
        return state
        
    def track_index_diff(self,index1, index2):
        if (self.waypoints.waypoints is None):
            return -1        
        N = len(self.waypoints.waypoints)
        if index2 >= index1 :
            return index2 - index1
        else:
            return N - index1 - 1 + index2
   
    def process_traffic_lights(self):
        """Finds closest visible traffic light, if one exists, and determines its
            location and color

        Returns:
            int: index of waypoint closes to the upcoming stop line for a traffic light (-1 if none exists)
            int: ID of traffic light color (specified in styx_msgs/TrafficLight)

        """
        if (self.waypoints is None):
            return (-1, TrafficLight.UNKNOWN)
        # List of positions that correspond to the line to stop in front of for a given intersection
        stop_line_positions = self.config['stop_line_positions']
        
        # now, for all stop_lines find nearest points (shoudl be done ONCE
        if (len(self.tl_wps)==0):           
            for i, stop_line in enumerate(stop_line_positions):
                tl_wp = self.get_closest_waypoint(Point(stop_line))
                self.tl_wps.append( (tl_wp+5) % len(self.waypoints.waypoints) ) # +1 to give extra margin towards the traffic light
            
        
        light = None
        
        if(self.pose):
            car_wp = self.get_closest_waypoint(self.pose.pose.position)

            
            # Now find the smallest distance to a traffic light wp from the car wp:
            minDist = self.track_index_diff(car_wp, self.tl_wps[0])
            light_index = 0
            for i in range(1, len(self.tl_wps)):
                dist = self.track_index_diff(car_wp, self.tl_wps[i])
                if dist > 150 / 0.63: #about 150 meters ON-TRACK 
                    continue
                if (dist < minDist):
                    minDist = dist                    
                    light_index = i
            
            light = self.lights[light_index]
            #print("Nearest Traffic light index  : ", light_index)
        
        if light:
            # print(light_wp, self.count)
            state = self.get_light_state(light)
            return self.tl_wps[light_index], state
        
        return -1, TrafficLight.UNKNOWN
       
   
    

    def process_traffic_lights_old(self):
        """Finds closest visible traffic light, if one exists, and determines its
            location and color

        Returns:
            int: index of waypoint closes to the upcoming stop line for a traffic light (-1 if none exists)
            int: ID of traffic light color (specified in styx_msgs/TrafficLight)

        """
        light = None
        # List of positions that correspond to the line to stop in front of for a given intersection
        stop_line_positions = self.config['stop_line_positions']
        if(self.pose):
            car_position = self.get_closest_waypoint(self.pose.pose.position)

            #TODO find the closest visible traffic light (if one exists)            
            light_wp = -1           
            for i, stop_line in enumerate(stop_line_positions):
                # computing the distance from the car to the traffic-light stop line                
                dis = (stop_line[0] - self.pose.pose.position.x)**2 + \
                    (stop_line[1] - self.pose.pose.position.y)**2
                # if the distance beyond a threshold (200^2 = 40000) skip    
                if dis > MAX_DISTANCE_SQR:
                    continue
                # Now, if the traffic light is potentially visible, find the
                # closest waypoint to it                
                stop_line_wp = self.get_closest_waypoint(Point(stop_line))
                
                if stop_line_wp >= car_position:
                    if (light_wp == -1) or (light_wp > stop_line_wp):
                        print(stop_line_wp, car_position, light_wp)
                        light_wp = stop_line_wp
                        light = self.lights[i]

        #rospy.logwarn("Found closest traffic light (waypoint) : %i" , light_wp)
        if light:
            # print(light_wp, self.count)
            state = self.get_light_state(light)
            return light_wp, state
        # self.waypoints = None
        return -1, TrafficLight.UNKNOWN
Пример #55
0
class BlobDetector:
    def __init__(self):
        self.bridge = CvBridge()
        self.map_frame_id = rospy.get_param('~map_frame_id', 'map')
        self.frame_id = rospy.get_param('~frame_id', 'base_link')
        self.object_frame_id = rospy.get_param('~object_frame_id', 'object')
        self.color_hue = rospy.get_param('~color_hue',
                                         10)  # 160=purple, 100=blue, 10=Orange
        self.color_range = rospy.get_param('~color_range', 15)
        self.color_saturation = rospy.get_param('~color_saturation', 50)
        self.color_value = rospy.get_param('~color_value', 50)
        self.border = rospy.get_param('~border', 10)
        self.config_srv = Server(BlobDetectorConfig, self.config_callback)

        params = cv2.SimpleBlobDetector_Params()
        # see https://www.geeksforgeeks.org/find-circles-and-ellipses-in-an-image-using-opencv-python/
        #     https://docs.opencv.org/3.4/d0/d7a/classcv_1_1SimpleBlobDetector.html

        params.thresholdStep = 10
        params.minThreshold = 50
        params.maxThreshold = 220
        params.minRepeatability = 2
        params.minDistBetweenBlobs = 10

        # Set Color filtering parameters
        params.filterByColor = False
        params.blobColor = 255

        # Set Area filtering parameters
        params.filterByArea = True
        params.minArea = 10
        params.maxArea = 5000000000

        # Set Circularity filtering parameters
        params.filterByCircularity = True
        params.minCircularity = 0.3

        # Set Convexity filtering parameters
        params.filterByConvexity = False
        params.minConvexity = 0.95

        # Set inertia filtering parameters
        params.filterByInertia = False
        params.minInertiaRatio = 0.1

        self.detector = cv2.SimpleBlobDetector_create(params)

        self.br = tf.TransformBroadcaster()
        self.listener = tf.TransformListener()

        self.image_pub = rospy.Publisher('image_detections',
                                         Image,
                                         queue_size=1)
        self.object_pub = rospy.Publisher('object_detected',
                                          String,
                                          queue_size=1)

        self.image_sub = message_filters.Subscriber('image', Image)
        self.depth_sub = message_filters.Subscriber('depth', Image)
        self.info_sub = message_filters.Subscriber('camera_info', CameraInfo)
        self.ts = message_filters.TimeSynchronizer(
            [self.image_sub, self.depth_sub, self.info_sub], 10)
        self.ts.registerCallback(self.image_callback)

    def __del__(self):
        self.file.close()

    def config_callback(self, config, level):
        rospy.loginfo(
            """Reconfigure Request: {color_hue}, {color_saturation}, {color_value}, {color_range}, {border}"""
            .format(**config))
        self.color_hue = config.color_hue
        self.color_range = config.color_range
        self.color_saturation = config.color_saturation
        self.color_value = config.color_value
        self.border = config.border
        return config

    def image_callback(self, image, depth, info):

        try:
            cv_image = self.bridge.imgmsg_to_cv2(image, "bgr8")
        except CvBridgeError as e:
            print(e)

        try:
            cv_depth = self.bridge.imgmsg_to_cv2(depth, "32FC1")
        except CvBridgeError as e:
            print(e)

        hsv = cv2.cvtColor(cv_image, cv2.COLOR_BGR2HSV)

        mask = cv2.inRange(
            hsv,
            np.array([
                self.color_hue - self.color_range, self.color_saturation,
                self.color_value
            ]), np.array([self.color_hue + self.color_range, 255, 255]))
        keypoints = self.detector.detect(mask)

        closestObject = [
            0, 0, 0
        ]  # Object pose (x,y,z) in camera frame (x->right, y->down, z->forward)
        if len(keypoints) > 0:
            cv_image = cv2.drawKeypoints(
                cv_image, keypoints, np.array([]), (0, 0, 255),
                cv2.DRAW_MATCHES_FLAGS_DRAW_RICH_KEYPOINTS)

            for i in range(0, len(keypoints)):
                if info.K[0] > 0 and keypoints[i].pt[
                        0] >= self.border and keypoints[i].pt[
                            0] < cv_image.shape[1] - self.border:
                    pts_uv = np.array(
                        [[[keypoints[i].pt[0], keypoints[i].pt[1]]]],
                        dtype=np.float32)
                    info_K = np.array(info.K).reshape([3, 3])
                    info_D = np.array(info.D)
                    info_P = np.array(info.P).reshape([3, 4])
                    pts_uv = cv2.undistortPoints(pts_uv, info_K, info_D,
                                                 info_P)
                    angle = np.arcsin(
                        -pts_uv[0][0][0]
                    )  # negative to get angle from forward x axis
                    x = pts_uv[0][0][0]
                    y = pts_uv[0][0][1]
                    #rospy.loginfo("(%d/%d) %f %f -> %f %f angle=%f deg", i+1, len(keypoints), keypoints[i].pt[0], keypoints[i].pt[1], x, y, angle*180/np.pi)

                    # Get depth.
                    u = int(x * info.P[0] + info.P[2])
                    v = int(y * info.P[5] + info.P[6])
                    depth = -1
                    if u >= 0 and u < cv_depth.shape[1]:
                        for j in range(0, cv_depth.shape[0]):
                            if cv_depth[j, u] > 0:
                                depth = cv_depth[j, u]
                                break
                                # is the depth contained in the blob?
                                if abs(j - v) < keypoints[i].size / 2:
                                    depth = cv_depth[j, u]
                                    break

                    if depth > 0 and (closestObject[2] == 0
                                      or depth < closestObject[2]):
                        closestObject[0] = x * depth
                        closestObject[1] = y * depth
                        closestObject[2] = depth

        # We process only the closest object detected
        if closestObject[2] > 0:
            # assuming the object is circular, use center of the object as position
            transObj = (closestObject[0], closestObject[1], closestObject[2])
            rotObj = tf.transformations.quaternion_from_euler(
                0, np.pi / 2, -np.pi / 2)
            self.br.sendTransform(transObj, rotObj, image.header.stamp,
                                  self.object_frame_id, image.header.frame_id)
            msg = String()
            msg.data = self.object_frame_id
            self.object_pub.publish(
                msg)  # signal that an object has been detected

            # Compute object pose in map frame
            try:
                self.listener.waitForTransform(self.map_frame_id,
                                               image.header.frame_id,
                                               image.header.stamp,
                                               rospy.Duration(0.5))
                (transMap, rotMap) = self.listener.lookupTransform(
                    self.map_frame_id, image.header.frame_id,
                    image.header.stamp)
            except (tf.LookupException, tf.ConnectivityException,
                    tf.ExtrapolationException) as e:
                print(e)
                return
            (transMap, rotMap) = multiply_transforms((transMap, rotMap),
                                                     (transObj, rotObj))

            # Compute object pose in base frame
            try:
                self.listener.waitForTransform(self.frame_id,
                                               image.header.frame_id,
                                               image.header.stamp,
                                               rospy.Duration(0.5))
                (transBase, rotBase) = self.listener.lookupTransform(
                    self.frame_id, image.header.frame_id, image.header.stamp)
            except (tf.LookupException, tf.ConnectivityException,
                    tf.ExtrapolationException) as e:
                print(e)
                return
            (transBase, rotBase) = multiply_transforms((transBase, rotBase),
                                                       (transObj, rotObj))

            distance = np.linalg.norm(transBase[0:2])
            angle = np.arcsin(transBase[1] / transBase[0])

            rospy.loginfo(
                "Object detected at [%f,%f] in %s frame! Distance and direction from robot: %fm %fdeg.",
                transMap[0], transMap[1], self.map_frame_id, distance,
                angle * 180.0 / np.pi)

        # debugging topic
        if self.image_pub.get_num_connections() > 0:
            cv_image = cv2.bitwise_and(cv_image, cv_image, mask=mask)
            try:
                self.image_pub.publish(
                    self.bridge.cv2_to_imgmsg(cv_image, "bgr8"))
            except CvBridgeError as e:
                print(e)
Пример #56
0
class TLDetector(object):
    def __init__(self):
        rospy.init_node('tl_detector')

        self.safe_visualizations = False  # saves camera images with detected bounding boxes
        self.use_classifier = True  # use the traffic light detection
        self.waypoint_range = 200
        self.current_tl_wp_idx = 0

        self.pose = None
        self.waypoints = None
        self.waypoints_2d = None
        self.waypoints_tree = None
        self.camera_image = None
        self.lights = []

        self.light_classifier = TLClassifier(self.safe_visualizations)

        rospy.Subscriber('/current_pose', PoseStamped, self.pose_cb)
        rospy.Subscriber('/base_waypoints', Lane, self.waypoints_cb)
        '''
        /vehicle/traffic_lights provides you with the location of the traffic light in 3D map space and
        helps you acquire an accurate ground truth data source for the traffic light
        classifier by sending the current color state of all traffic lights in the
        simulator. When testing on the vehicle, the color state will not be available. You'll need to
        rely on the position of the light and the camera image to predict it.
        '''
        rospy.Subscriber('/vehicle/traffic_lights', TrafficLightArray,
                         self.traffic_cb)
        rospy.Subscriber('/image_color', Image, self.image_cb)

        config_string = rospy.get_param("/traffic_light_config")
        self.config = yaml.load(config_string)
        self.stop_line_positions = self.config['stop_line_positions']
        # rospy.logwarn(self.config)

        self.is_site = self.config['is_site']

        output_dir = os.path.join('./data/dataset/',
                                  'site' if self.is_site else 'simulator')
        self.image_saver = ImageSaver(None, output_dir)

        self.upcoming_red_light_pub = rospy.Publisher('/traffic_waypoint',
                                                      Int32,
                                                      queue_size=1)
        self.bridge = CvBridge()
        self.listener = tf.TransformListener()
        self.state = TrafficLight.UNKNOWN
        self.last_state = TrafficLight.UNKNOWN
        self.last_wp = -1
        self.state_count = 0
        self.no_of_wp = None
        self.idx_of_closest_wp_to_car = None
        self.line_wp_idxs_list = []
        self.has_image = False

        rospy.spin()

    def pose_cb(self, msg):
        self.pose = msg

    def waypoints_cb(self, waypoints):
        self.waypoints = waypoints
        self.no_of_wp = len(self.waypoints.waypoints)
        if not self.waypoints_2d:
            self.waypoints_2d = [[
                waypoint.pose.pose.position.x, waypoint.pose.pose.position.y
            ] for waypoint in waypoints.waypoints]
            self.waypoints_tree = KDTree(self.waypoints_2d)

    def traffic_cb(self, msg):
        self.lights = msg.lights
        # rospy.logwarn(msg.lights)

    def image_cb(self, msg):
        """Identifies red lights in the incoming camera image and publishes the index
            of the waypoint closest to the red light's stop line to /traffic_waypoint

        Args:
            msg (Image): image from car-mounted camera

        """

        if self.is_site:
            self.has_image = True
            self.camera_image = msg
            tl_in_range = self.traffic_light_in_range()
            light_wp, state = self.process_traffic_lights()
            '''
            Publish upcoming red lights at camera frequency.
            Each predicted state has to occur `STATE_COUNT_THRESHOLD` number
            of times till we start using it. Otherwise the previous stable state is
            used.
            '''
            if self.state != state:
                self.state_count = 0
                self.state = state
            elif self.state_count >= STATE_COUNT_THRESHOLD:
                self.last_state = self.state
                light_wp = light_wp if state == TrafficLight.RED else -1
                self.last_wp = light_wp
                self.upcoming_red_light_pub.publish(Int32(light_wp))
            else:
                self.upcoming_red_light_pub.publish(Int32(self.last_wp))
            self.state_count += 1

        else:
            if self.waypoints_tree and self.light_classifier:
                tl_in_range = self.traffic_light_in_range()
                rospy.logwarn("Car wp: {},    TL in range: {}".format(
                    self.idx_of_closest_wp_to_car, tl_in_range))
                if tl_in_range:
                    rospy.logwarn(
                        "TL wp:  {}, TL idx: {} in range {} wp".format(
                            self.line_wp_idxs_list[
                                self.current_tl_wp_idx %
                                len(self.line_wp_idxs_list)],
                            self.current_tl_wp_idx, self.waypoint_range))
                    self.has_image = True
                    self.camera_image = msg
                    light_wp, state = self.process_traffic_lights()
                    '''
                    Publish upcoming red lights at camera frequency.
                    Each predicted state has to occur `STATE_COUNT_THRESHOLD` number
                    of times till we start using it. Otherwise the previous stable state is
                    used.
                    '''
                    if self.state != state:
                        self.state_count = 0
                        self.state = state
                    elif self.state_count >= STATE_COUNT_THRESHOLD:
                        self.last_state = self.state
                        light_wp = light_wp if state == TrafficLight.RED or state == TrafficLight.YELLOW else -1
                        self.last_wp = light_wp
                        self.upcoming_red_light_pub.publish(Int32(light_wp))
                    else:
                        self.upcoming_red_light_pub.publish(Int32(
                            self.last_wp))
                    self.state_count += 1

    def traffic_light_in_range(self):
        """Identifies if the closest traffic light to the vehicles position
            is within a given number of waypoints ahead of the vehicle.

        Returns:
            boolean: if a traffic light satisfies these parameters or not
        """

        offest = 25  # approx offset (in waypoints) from the traffic light and the stop line.

        if self.pose:
            self.idx_of_closest_wp_to_car = self.get_closest_waypoint(
                self.pose.pose.position.x, self.pose.pose.position.y)
            if len(self.line_wp_idxs_list) < 1:
                for i, light in enumerate(self.lights):
                    line = self.stop_line_positions[i]
                    self.line_wp_idxs_list.append(
                        self.get_closest_waypoint(line[0], line[1]))

            if self.idx_of_closest_wp_to_car \
                    > self.line_wp_idxs_list[self.current_tl_wp_idx % len(self.line_wp_idxs_list)]:
                self.current_tl_wp_idx += 1
            if self.idx_of_closest_wp_to_car + self.waypoint_range \
                    > self.line_wp_idxs_list[self.current_tl_wp_idx % len(self.line_wp_idxs_list)] + offest:
                return True
            else:
                return False

    def get_closest_waypoint(self, x, y):
        """Identifies the closest path waypoint to the given position
            https://en.wikipedia.org/wiki/Closest_pair_of_points_problem
        Args:
            x (float): position to match a waypoint to
            y (float): position to match a waypoint to

        Returns:
            int: index of the closest waypoint in self.waypoints

        """

        closest_idx = self.waypoints_tree.query([x, y], 1)[1]
        return closest_idx

    def get_light_state(self, light):
        """Determines the current color of the traffic light

        Args:
            light (TrafficLight): light to classify

        Returns:
            int: ID of traffic light color (specified in styx_msgs/TrafficLight)
        """

        if not self.has_image:
            return False

        if not self.use_classifier:
            rospy.loginfo('Light state: %s', light.state)
            return light.state

        cv_image = self.bridge.imgmsg_to_cv2(self.camera_image, 'rgb8')
        classified_state = self.light_classifier.get_classification(cv_image)

        if not self.is_site:
            rospy.loginfo("Sim ground truth state: {}".format(
                self.state_to_string(light.state)))

        rospy.loginfo("Classified state:       {}".format(
            self.state_to_string(classified_state)))

        return classified_state

    @staticmethod
    def state_to_string(state):
        if state == TrafficLight.RED:
            return "Red"
        elif state == TrafficLight.YELLOW:
            return "Yellow"
        elif state == TrafficLight.GREEN:
            return "Green"
        return "Unknown"

    def process_traffic_lights(self):
        """Finds closest visible traffic light, if one exists, and determines its
            location and color

        Returns:
            int: index of waypoint closes to the upcoming stop line for a traffic light (-1 if none exists)
            int: ID of traffic light color (specified in styx_msgs/TrafficLight)
        """

        closest_light = None
        line_wp_idx = None

        if self.pose:
            diff = self.no_of_wp
            for i, light in enumerate(self.lights):
                idx_of_closest_wp_to_line = self.line_wp_idxs_list[i]

                d = idx_of_closest_wp_to_line - self.idx_of_closest_wp_to_car
                if diff > d >= 0:
                    diff = d
                    closest_light = light
                    line_wp_idx = idx_of_closest_wp_to_line

        if closest_light:
            return line_wp_idx, self.get_light_state(closest_light)

        return -1, TrafficLight.UNKNOWN