查找形状内的像素索引:Opencv 和 Python

Find pixel indices within a shape: Opencv and Python

假设我有一个从预处理步骤中收到的中空、弯曲(不一定是凸面)形状的掩码:

我现在想尝试 select 在 内部 出现的所有像素,并将它们添加到蒙版中,如下所示:

如何在 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()

使用floodFill填充圆的外侧。然后用np.where求圆内的像素

cv2.floodFill(circle_mask, None, (0, 0), 1)
np.where(circle_mask == 0)

还有另外两种方法:

方法一: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)

方法二: cv2.findContours + cv2.fillPoly

再次找到等高线,然后使用不同的填充函数进行填充

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

完整代码

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()

您也可以使用scipy.ndimage.binary_fill_holes