红绿灯硬分类方法

红绿灯硬分类方法

  1. 设置阈值划分红绿灯。

    import cv2
    import numpy as np
    
    
    def detect_red_and_yellow(img, Threshold=0.01):
        """
        detect red and yellow
        :param img:
        :param Threshold:
        :return:
        """
    
        desired_dim = (30, 90)  # width, height
        img = cv2.resize(np.array(img), desired_dim, interpolation=cv2.INTER_LINEAR)
        img_hsv = cv2.cvtColor(img, cv2.COLOR_RGB2HSV)
    
        # lower mask (0-10)
        lower_red = np.array([0, 70, 50])
        upper_red = np.array([10, 255, 255])
        mask0 = cv2.inRange(img_hsv, lower_red, upper_red)
    
        # upper mask (170-180)
        lower_red1 = np.array([170, 70, 50])
        upper_red1 = np.array([180, 255, 255])
        mask1 = cv2.inRange(img_hsv, lower_red1, upper_red1)
    
        # defining the Range of yellow color
        lower_yellow = np.array([21, 39, 64])
        upper_yellow = np.array([40, 255, 255])
        mask2 = cv2.inRange(img_hsv, lower_yellow, upper_yellow)
    
        # red pixels' mask
        mask = mask0 + mask1 + mask2
    
        # Compare the percentage of red values
        rate = np.count_nonzero(mask) / (desired_dim[0] * desired_dim[1])
    
        if rate > Threshold:
            return True
        else:
            return False
    
    
    
    
    1. 对HSV空间进行划分,根据图片特征在HSV空间的位置划分红绿灯。

      import numpy as np
      from skimage.color import rgb2hsv
      import cv2 as cv
      
      
      def rgb2grey(rbgImage):
          return cv.cvtColor(rbgImage, cv.COLOR_BGR2GRAY)
      
      
      def channel_percentile(single_chan_image, percentile):
          sq_image = np.squeeze(single_chan_image)
          assert len(sq_image.shape) < 3
      
          thres_value = np.percentile(sq_image.ravel(), percentile)
      
          return float(thres_value) / 255.0
      
      
      def high_saturation_region_mask(hsv_image, s_thres=0.6):
          if hsv_image.dtype == np.int:
              idx = (hsv_image[:, :, 1].astype(np.float) / 255.0) < s_thres
          else:
              idx = (hsv_image[:, :, 1].astype(np.float)) < s_thres
          mask = np.ones_like(hsv_image[:, :, 1])
          mask[idx] = 0
          return mask
      
      
      def get_masked_hue_image(hsv_test_image):
          s_thres_val = channel_percentile(hsv_test_image[:, :, 1], percentile=70)
          v_thres_val = channel_percentile(hsv_test_image[:, :, 2], percentile=70)
          val_mask = high_value_region_mask(hsv_test_image, v_thres=v_thres_val)
          sat_mask = high_saturation_region_mask(hsv_test_image, s_thres=s_thres_val)
          masked_hue_image = hsv_test_image[:, :, 0]
          return masked_hue_image
      
      
      def high_value_region_mask(hsv_image, v_thres=0.6):
          if hsv_image.dtype == np.int:
              idx = (hsv_image[:, :, 2].astype(np.float) / 255.0) < v_thres
          else:
              idx = (hsv_image[:, :, 2].astype(np.float)) < v_thres
          mask = np.ones_like(hsv_image[:, :, 2])
          mask[idx] = 0
          return mask
      
      
      def get_masked_hue_values(rgb_image):
          """
          Get the pixels in the RGB image that has high saturation (S) and value (V) in HSV chanels
      
          :param rgb_image: image (height, width, channel)
          :return: a 1-d array
          """
      
          hsv_test_image = rgb2hsv(rgb_image)
          s_thres_val = channel_percentile(hsv_test_image[:, :, 1], percentile=30)
          v_thres_val = channel_percentile(hsv_test_image[:, :, 2], percentile=70)
          val_mask = high_value_region_mask(hsv_test_image, v_thres=v_thres_val)
          sat_mask = high_saturation_region_mask(hsv_test_image, s_thres=s_thres_val)
          masked_hue_image = hsv_test_image[:, :, 0] * 180
          # Note that the following statement is not equivalent to
          # masked_hue_1d= (maksed_hue_image*np.logical_and(val_mask,sat_mask)).ravel()
          # Because zero in hue channel means red, we cannot just set unused pixels to zero.
          masked_hue_1d = masked_hue_image[np.logical_and(val_mask, sat_mask)].ravel()
      
          return masked_hue_1d
      
      
      def convert_to_hue_angle(hue_array):
          """
          Convert the hue values from [0,179] to radian degrees [-pi, pi]
      
          :param hue_array: array-like, the hue values in degree [0,179]
          :return: the angles of hue values in radians [-pi, pi]
          """
      
          hue_cos = np.cos(hue_array * np.pi / 90)
          hue_sine = np.sin(hue_array * np.pi / 90)
      
          hue_angle = np.arctan2(hue_sine, hue_cos)
      
          return hue_angle
      
      
      def conver_to_hue_angle_from_01(hue_value):
          return (hue_value + np.pi) / (2 * np.pi)
      
      
      def get_rgy_color_mask(hue_value, from_01=False):
          """
          return a tuple of np.ndarray that sets the pixels with red, green and yellow matrices to be true
      
          :param hue_value:
          :param from_01: True if the hue values is scaled from 0-1 (scikit-image), otherwise is -pi to pi
          :return:
          """
      
          if from_01:
              n_hue_value = conver_to_hue_angle_from_01(hue_value)
          else:
              n_hue_value = hue_value
      
          red_index = np.logical_and(n_hue_value < (0.125 * np.pi), n_hue_value > (-0.125 * np.pi))
      
          green_index = np.logical_and(n_hue_value > (0.66 * np.pi), n_hue_value < np.pi)
      
          yellow_index = np.logical_and(n_hue_value > (0.25 * np.pi), n_hue_value < (5.0 / 12.0 * np.pi))
      
          return red_index, green_index, yellow_index
      
      
      def classify_color_by_range(hue_value):
          """
          Determine the color (red, yellow or green) in a hue value array
      
          :param hue_value: hue_value is radians
          :return: the color index ['red', 'yellow', 'green', '_', 'unknown']
          """
      
          red_index, green_index, yellow_index = get_rgy_color_mask(hue_value)
      
          color_counts = np.array([np.sum(red_index) / len(hue_value),
                                   np.sum(yellow_index) / len(hue_value),
                                   np.sum(green_index) / len(hue_value)])
      
          color_text = ['red', 'yellow', 'green', '_', 'unknown']
      
          min_index = np.argmax(color_counts)
      
          return min_index, color_text[min_index]
      
      
      def classify_color_cropped_image(rgb_image):
          """
          Full pipeline of classifying the traffic light color from the traffic light image
      
          :param rgb_image: the RGB image array (height,width, RGB channel)
          :return: the color index ['red', 'yellow', 'green', '_', 'unknown']
          """
      
          hue_1d_deg = get_masked_hue_values(rgb_image)
      
          if len(hue_1d_deg) == 0:
              return 4, 'unknown'
      
          hue_1d_rad = convert_to_hue_angle(hue_1d_deg)
      
          return classify_color_by_range(hue_1d_rad)
      
      

你可能感兴趣的:(图像处理,分类,python,numpy)