Найти индексы пикселей внутри фигуры: Opencv и Python - PullRequest
3 голосов
/ 18 февраля 2020

Предположим, у меня есть маска полой, изогнутой (и не обязательно выпуклой) формы, которую я получил на этапах предварительной обработки:

Hollow circle mask

Теперь я хочу попробовать выбрать все пиксели, которые встречаются внутри этой фигуры, и добавить их в маску следующим образом:

Filled circle mask

Как я могу сделать это в Python?


Код для генерации примеров:

import cv2
import numpy as np
import matplotlib.pyplot as plt

# Parameters for creating the circle
COLOR_BLUE = (255, 0, 0)
IMAGE_SHAPE = (256, 256, 3)
CIRCLE_CENTER = tuple(np.array(IMAGE_SHAPE) // 2)[:-1]
CIRCLE_RADIUS = 30
LINE_THICKNESS = 5 # Change to -1 for example of filled circle

# Draw on a circle
img = np.zeros(IMAGE_SHAPE, dtype=np.uint8)
img_circle = cv2.circle(img, CIRCLE_CENTER, CIRCLE_RADIUS, COLOR_BLUE, LINE_THICKNESS)
circle_mask = img_circle[:, :, 0]

# Show the image
plt.axis("off")
plt.imshow(circle_mask)
plt.show()

Ответы [ 3 ]

4 голосов
/ 18 февраля 2020

Используйте floodFill, чтобы заполнить внешнюю часть круга. Затем используйте np.where, чтобы найти пиксели внутри круга

cv2.floodFill(circle_mask, None, (0, 0), 1)
np.where(circle_mask == 0)
1 голос
/ 18 февраля 2020

Вот два других метода:

Метод № 1: cv2.findContours + cv2.drawContours

Найдите контуры, затем заполните контур

cnts = cv2.findContours(circle_mask, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
cnts = cnts[0] if len(cnts) == 2 else cnts[1]
for c in cnts:
    cv2.drawContours(circle_mask, [c], -1, (255,255,255), -1)

Метод № 2: cv2.findContours + cv2.fillPoly

Снова найдите контуры, затем заполните, используя другую функцию заполнения

cv2.fillPoly(circle_mask, cnts, (255,255,255))

enter image description here

Полный код

import cv2
import numpy as np

# Parameters for creating the circle
COLOR_BLUE = (255, 0, 0)
IMAGE_SHAPE = (256, 256, 3)
CIRCLE_CENTER = tuple(np.array(IMAGE_SHAPE) // 2)[:-1]
CIRCLE_RADIUS = 30
LINE_THICKNESS = 5 # Change to -1 for example of filled circle

# Draw on a circle
img = np.zeros(IMAGE_SHAPE, dtype=np.uint8)
img_circle = cv2.circle(img, CIRCLE_CENTER, CIRCLE_RADIUS, COLOR_BLUE, LINE_THICKNESS)
circle_mask = img_circle[:, :, 0].astype(np.uint8)

# Method #1
cnts = cv2.findContours(circle_mask, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
cnts = cnts[0] if len(cnts) == 2 else cnts[1]
for c in cnts:
    cv2.drawContours(circle_mask, [c], -1, (255,255,255), -1)

# Method #2
# cv2.fillPoly(circle_mask, cnts, (255,255,255))

# Show the image
cv2.imshow('circle_mask', circle_mask)
cv2.waitKey()
0 голосов
/ 18 февраля 2020

Вы также можете использовать scipy.ndimage.binary_fill_holes.

...