Как удалить полилинию из изображения RGB с помощью numpy

#python #numpy #opencv

#python #numpy #opencv

Вопрос:

Я не уверен, что было бы лучшим способом удалить вертикальную полилинию из изображения. Эта строка начинается с самого верха изображения до самого низа. Ввод — это image with three channels и array of y indices of the line . На выходе будет то же входное изображение, но без полилинии. Например, если первой формой изображения является (5, 10,3) , то окончательная форма изображения должна быть (5, 9, 3) после удаления полилинии.

Пример ввода:

Изображение:

 np.array([[[0, 20, 0, 0, 255, 0, 0, 0, 0, 0],
           [0, 20, 0, 0, 255, 0, 0, 0, 0, 0],
           [0, 56, 0, 0, 0, 255, 0, 0, 0, 0],
           [0, 58, 0, 0, 0, 255, 0, 0, 0, 0],
           [0, 0, 0, 0, 0, 0, 255, 0, 0, 0]],
          [[0, 0, 0, 0, 255, 0, 0, 0, 30, 0],
           [0, 0, 0, 0, 255, 0, 0, 0, 31, 0],
           [0, 0, 0, 0, 0, 255, 0, 0, 32, 0],
           [0, 0, 0, 0, 0, 255, 0, 0, 31, 0],
           [0, 0, 0, 0, 0, 0, 255, 0, 0, 0]],
          [[1, 0, 0, 0, 255, 0, 0, 0, 0, 0],
           [1, 0, 0, 0, 255, 0, 0, 0, 0, 0],
           [1, 0, 0, 0, 0, 255, 0, 0, 0, 0],
           [1, 0, 0, 0, 0, 255, 0, 0, 0, 0],
           [1, 0, 0, 0, 0, 0, 255, 0, 0, 0]]])
  

Примечание: размер здесь равен (3, 5, 10) для иллюстрации. Форма изображения будет (5, 10, 3). Мы хотим удалить белую полилинию

Полилиния:

 np.array([4, 4, 5, 5, 6])
  

Пример вывода

 np.array([[[0, 20, 0, 0, 0, 0, 0, 0, 0],
           [0, 20, 0, 0, 0, 0, 0, 0, 0],
           [0, 56, 0, 0, 0, 0, 0, 0, 0],
           [0, 58, 0, 0, 0, 0, 0, 0, 0],
           [0, 0, 0, 0, 0, 0, 0, 0, 0]],
          [[0, 0, 0, 0, 0, 0, 0, 30, 0],
           [0, 0, 0, 0, 0, 0, 0, 31, 0],
           [0, 0, 0, 0, 0, 0, 0, 32, 0],
           [0, 0, 0, 0, 0, 0, 0, 31, 0],
           [0, 0, 0, 0, 0, 0, 0, 0, 0]],
          [[1, 0, 0, 0, 0, 0, 0, 0, 0],
           [1, 0, 0, 0, 0, 0, 0, 0, 0],
           [1, 0, 0, 0, 0, 0, 0, 0, 0],
           [1, 0, 0, 0, 0, 0, 0, 0, 0],
           [1, 0, 0, 0, 0, 0, 0, 0, 0]]])
  

Примечание: размер теперь равен (3, 5, 9)

Мой код

 def remove_polyline(image, polyline):
    h, w = image.shape[:2]
    res_image = np.zeros((h, w - 1))

    for i in range(h):
        left_section = image[i, :polyline[i]]
        right_section = image[i, polyline[i] 1:]
        res_image[i, :] = np.dstack((left_section, right_section))

    return res_image
  

Я знаю, что это сработает для изображений в оттенках серого, но не уверен в 3-канальных изображениях

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

1. Просто нарисуйте поверх нее цвет фона. Смотрите cv2.polylines() в docs.opencv.org/4.1.1/d6/d6e /…

2. Это другое, мне нужно уменьшить изображение, удалив полилинию

Ответ №1:

Обратите внимание, что ваш ввод имеет форму (3,5,10) вместо (5,10,3) . Этот ответ предполагает последнее:

 def remove_polyline(s, polyline):
    mask = np.arange(s.shape[1]) != polyline[ :, None]
    return s[mask,:].reshape(s[:,:-1].shape).copy()

r = remove_polyline(image, polyline)
plt.imshow(r)
  

Вывод:

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

Ответ №2:

Вы можете попробовать это.

 def remove_polyline(image, polyline):
    h, w, c = image.shape
    res_image = np.zeros((h, w - 1, c))

    for i in range(h):
        left_section = image[i, :polyline[i], :]
        right_section = image[i, polyline[i] 1:, :]
        res_image[i, :, :] = np.vstack((left_section, right_section))

    return res_image
  

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

1. Я думаю, вам просто нужно добавить тип, res_image чтобы он был: res_image = np.zeros((h, w - 1, c), dtype=int)

2. Хорошо, это имеет смысл.