[英]how to get only contour area color range
我想獲得輪廓區域顏色范圍並做一些條件,例如這是輸入圖像: 下面是查找輪廓的代碼:
import cv2
img = cv2.imread('D:/original.png', cv2.IMREAD_UNCHANGED)
#convert img to grey
img_grey = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
#set a thresh
thresh = 100
#get threshold image
ret,thresh_img = cv2.threshold(img_grey, thresh, 255, cv2.THRESH_BINARY)
#find contours
contours, hierarchy = cv2.findContours(thresh_img, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
現在我正在嘗試獲取每個輪廓顏色並編寫條件,例如:
如果 contours[0] 在顏色范圍 ((100,100,100),(200,200,200)) 中,則 drawContour
我要做的所有事情是:獲取每個輪廓區域並檢查所選輪廓是否在特定顏色范圍內。
為了提取按顏色區分的單個輪廓,解決此問題的邏輯方法是使用不同的 colors 而不是將圖像轉換為grayscale
。
您可以在單個頻道上工作。 例如,對於blue
通道:
thresh = 100
ret,thresh_img = cv2.threshold(b, thresh, 255, cv2.THRESH_BINARY)
然后結合按bit_wise
操作,您可以提取特定的輪廓。
另一種方法是用Canny
運算符替換threshold
運算符。
thresh1 = 40
thresh2 = 120
#get canny image
thresh_img = cv2.Canny(img[:,:,0], thresh1,thresh2)
#find contours
contours, hierarchy = cv2.findContours(thresh_img, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
OpenCV 文檔建議使用Canny
作為輪廓的預處理。
我們可以從cv2.kmeans開始執行顏色聚類 - 類似於以下教程中描述的內容。
結果是標簽列表。
每個 label(標簽 0、label 1,...)代表屬於特定顏色簇的所有像素。
將 K-Means 應用於 colors 聚類的示例:
# Reshape the image into a 2D array with one row per pixel and three columns for the color channels.
data = image.reshape((cols * rows, 3))
# Perform K-Means clustering on the image.
criteria = (cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_MAX_ITER, 10, 1.0)
_, labels, centroids = cv2.kmeans(data, K, None, criteria, 10, cv2.KMEANS_RANDOM_CENTERS)
迭代標簽,並創建一個包含255
的掩碼,其中labels == k
:
mask = np.zeros((rows*cols, 1), np.uint8) # Create a zerod mask in the size of image.
mask[labels == k] = 255 # Place 255 where labels == k (all labels equals 0 are going to be 255 then all labels equals 1...)
mask = mask.reshape((rows, cols)) # Reshape the mask back to the size of the image.
對於每個面具應用以下階段:
x, y = tuple(c[0][0])
。color = original_image[y, x]
。cv2.drawContours(colored_mask, [c], 0, color.tolist(), -1)
。完整的代碼示例:
import cv2
import numpy as np
K = 16 # Number of color clusters (16 is a bit larger than the accrual number of colors).
# Load the image and convert it float32 (kmeans requires float32 type).
original_image = cv2.imread('original.png')
image = original_image.astype(np.float32)
cols, rows = image.shape[1], image.shape[0]
# Reshape the image into a 2D array with one row per pixel and three columns for the color channels.
data = image.reshape((cols * rows, 3))
# Perform K-Means clustering on the image.
criteria = (cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_MAX_ITER, 10, 1.0)
_, labels, centroids = cv2.kmeans(data, K, None, criteria, 10, cv2.KMEANS_RANDOM_CENTERS)
# Convert the labels back into an image (for testing).
quantized_image = centroids[labels].reshape(image.shape).astype(np.uint8)
# Save the quantized_image image (for testing).
cv2.imwrite('quantized_image.png', quantized_image)
for k in range(K):
mask = np.zeros((rows*cols, 1), np.uint8) # Create a zeroed mask in the size of image.
mask[labels == k] = 255 # Place 255 where labels == k (all labels equals 0 are going to be 255 then all labels equals 1...)
mask = mask.reshape((rows, cols)) # Reshape the mask back to the size of the image.
#cv2.imshow(f'mask {k}', mask) # Show mask for testing
cnts = cv2.findContours(mask, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)[0] # Find contours
for c in cnts:
area_tresh = 500
area = cv2.contourArea(c)
if area > area_tresh: # Ignore relatively small contours
colored_mask = np.zeros_like(original_image) # Initialize colored_mask with zeros
x, y = tuple(c[0][0]) # First coordinate in the contour
color = original_image[y, x] # Get the color of the pixel in that coordinate
cv2.drawContours(colored_mask, [c], 0, color.tolist(), -1) # Draw contour with the specific color
cv2.imshow(f'colored_mask {k}', colored_mask) # Show colored_mask for testing
cv2.imwrite(f'colored_mask_{k}.png', colored_mask) # Save as PNG for testing
continue # Assume only the first large contour is relevant - continue to next iteration
cv2.waitKey()
cv2.destroyAllWindows()
很少有 output 個樣本:
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.