import cv2
import numpy as np
img = cv2.imread('contiguous_zones.png')
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) # Convert to grayscale.
_, thresh = cv2.threshold(gray, 0, 255, cv2.THRESH_OTSU + cv2.THRESH_BINARY_INV) # Apply automatic thresholding (use THRESH_OTSU) and invert polarity since background is white.
# Find contours (use cv2.RETR_EXTERNAL for ignoring the inner contours).
contours, hierarchy = cv2.findContours(thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
# Iterate contours
for c in contours:
# Draw contour over the original image with the mean color.
cv2.drawContours(img, [c], 0, (177, 35, 159), -1)
mask = np.zeros((img.shape[0], img.shape[1]), np.uint8)
cv2.drawContours(mask, [c], 0, 255, -1)
mask = mask & thresh # Remove inner part from the mask (black pixels in thresh).
mask = cv2.erode(mask, np.ones((5, 5), np.uint8)) # Erode the mask for improving accuracy (there are few white pixels from the outer contour).
mean_color = cv2.mean(img, mask=mask) # Compute the mean color of the pixels inside the mask.
mean_color = np.round(mean_color[0:3]).astype(int) # Take first 3 elements applies BGR - (the 4'th element is alpha) and convert to int.
完整代码示例:
import cv2
import numpy as np
img = cv2.imread('contiguous_zones.png')
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) # Convert to grayscale.
_, thresh = cv2.threshold(gray, 0, 255, cv2.THRESH_OTSU + cv2.THRESH_BINARY_INV) # Apply automatic thresholding (use THRESH_OTSU) and invert polarity since background is white.
# Find contours (use cv2.RETR_EXTERNAL for ignoring the inner contours).
contours, hierarchy = cv2.findContours(thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
# Iterate contours
for c in contours:
# Get the average color inside a contour
# The mean color excludes the inner white pixels
############################################################################
# https://stackoverflow.com/questions/54316588/get-the-average-color-inside-a-contour-with-open-cv
mask = np.zeros((img.shape[0], img.shape[1]), np.uint8)
cv2.drawContours(mask, [c], 0, 255, -1)
mask = mask & thresh # Remove inner part from the mask (black pixels in thresh).
mask = cv2.erode(mask, np.ones((5, 5), np.uint8)) # Erode the mask for improving accuracy (there are few white pixels from the outer contour).
#cv2.imshow('mask', mask) # Show mask for testing
#cv2.waitKey()
mean_color = cv2.mean(img, mask=mask) # Compute the mean color of the pixels inside the mask.
mean_color = np.round(mean_color[0:3]).astype(int) # Take first 3 elements applies BGR - (the 4'th element is alpha) and convert to int.
############################################################################
# Draw contour over the original image with the mean color.
cv2.drawContours(img, [c], 0, mean_color.tolist(), -1)
# Show results for testing:
cv2.imshow('thresh', thresh)
cv2.imshow('img', img)
cv2.waitKey()
cv2.destroyAllWindows()
1条答案
按热度按时间iq3niunx1#
使用cv2.findContours,我们可以找到外部轮廓,然后使用cv2.drawContours用所需的颜色填充轮廓。
更有趣的部分是自动计算“填充颜色”(假设这是必需的)。
注:我们还可以假设同一图像中的不同轮廓可能具有不同的颜色。
假设我们事先知道颜色,使用以下阶段:
代码示例:
查找每个轮廓的颜色:
基于following answer,我们可以找到轮廓内的平均颜色。
有一个小的变化-我们必须忽略轮廓内的白色像素。
为了提高精度,我们还可以将掩模放大一点。
查找轮廓
c
颜色的示例代码:完整代码示例:
img
(输出):thresh
: