Я использовал opencv для обнаружения облака, но есть ошибка

#python #opencv #machine-learning #computer-vision #detection

#python #opencv #машинное обучение #компьютерное зрение #обнаружение

Вопрос:

Я использовал OpenCV для обнаружения облака.. он может обнаруживать белые облака, но когда облака темные, он их не обнаруживает.

итак, здесь мое обнаружение таково: > белая маскировка предназначена для облаков, а черная — для неба.

вот как это выглядит:

это исходное изображение

введите описание изображения здесь

это замаскированное изображение

введите описание изображения здесь

Вот нарисованные облака, которые должны быть замаскированы белым цветом.. но здесь это считается небом и замаскировано черным цветом. :

введите описание изображения здесь

все должно быть белым, поскольку неба нет, это просто темные облака..

как я могу решить эту проблему? Спасибо

вот используемый код:

 def preprocess(image):
    """ Preprocess 'image' to help separate cloud and sky. """
    B, G, R = cv2.split(image) # extract the colour channels

    # construct a ratio between the blue and red channel sum and difference
    BR_sum  = B   R
    BR_diff = B - R
    # handle X/0 and 0/0 errors, and remove NaNs (not a number)
    with np.errstate(divide='ignore', invalid='ignore'):
        BR_ratio = BR_diff / BR_sum
        BR_ratio = np.nan_to_num(BR_ratio)

    # normalize to 0-255 range and convert to 8-bit unsigned integers
    return cv2.normalize(BR_ratio, None, 0, 255, cv2.NORM_MINMAX) 
              .astype(np.uint8)

def makebinary(imagepath, radiusMask = None):
    startTime = datetime.now()

    # read in the image and shrink for faster processing
    image   = cv2.imread(imagepath)
    scale   = 0.2
    smaller = cv2.resize(image, (0,0), fx=scale, fy=scale)
    center  = [dim / 2 for dim in smaller.shape[:2]]

    preprocessed = preprocess(smaller.astype(float))

    if radiusMask:
        # apply a circular mask to get only the pixels of interest
        from cmask import cmask
        mask = cmask(index, scale * radiusMask, resized).astype(bool)
    else:
        mask = np.ones(preprocessed.shape).astype(bool)
    
    masked = preprocessed[mask]

    # use Otsu's method to separate clouds and sky
    threshold, result = cv2.threshold(masked, 0, 255,
                                      cv2.THRESH_BINARY cv2.THRESH_OTSU)

    # invert the result so clouds are white (255) and sky is black (0)
    inverted = cv2.bitwise_not(result)
  

вот cmask:

 import numpy as np

def cmask(center, radius, image):
  c_y, c_x = center
  num_y, num_x = image.shape[:2]

  image_mask = np.ones((num_y, num_x))
  y, x = np.ogrid[-c_y:num_y-c_y, -c_x:num_x-c_x]
  # remove components outside the circle
  image_mask[(x*x   y*y) > radius*radius] = 0
  return(image_mask)
  

Комментарии:

1. пожалуйста, используйте Microsoft paint или snipping tool, чтобы нарисовать то, чего вы хотите достичь. мы увидели входное и выходное изображение. но мы не знаем, какой результат вы хотите, чтобы он был

2. @Dr Yuan Shenghai, спасибо, я обновил сообщение.