Это можно сделать разными способами в зависимости от необходимости. Одним простым способом может быть:
Во-первых, отфильтруйте ROI. Итак, мы знаем 3 вещи, ROI - это белый цвет, это круг, и мы знаем его приблизительную площадь.
Для белого цвета:
def detect_white(img):
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
_, thresh = cv2.threshold(gray, 220, 255, cv2.THRESH_BINARY)
return thresh
Хотя вам нужно будет поиграть с алгоритмом обнаружения белого, как по вашей необходимости. Некоторые хорошие способы обнаружения белого были бы с порогом (как выше), используя цветовое пространство HSL, так как белизна тесно связана с яркостью (cv2.cvtColor(img, cv2.COLOR_BGR2HLS
) и c.
Так в приведенном ниже коде, сначала мы отфильтровываем область интереса по белому цвету, а затем по форме и площади этих белых контуров.
image = cv2.imread("path/to/your/image")
white_only = detect_white(image)
contours, hierarchy = cv2.findContours(white_only, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
circles = []
for contour in contours:
epsilon = 0.01 * cv2.arcLength(contour, True)
approx = cv2.approxPolyDP(contour, epsilon, True)
area = cv2.contourArea(contour)
if len(approx) > 12 and area > 1000 and area < 3000:
circles.append(contour)
# Now the list circles would have all such
# contours satisfying the above conditions
# If len(circles) != 1 or isn't the circle you
# desire, more filtering is required
cv2.drawContours(image, circles, -1, (0, 255, 0), 3)
Выбор контура зависит от площади и вершин (как возвращено cv2. approxPolyDP()
).
Как и на вашем изображении, большой белый круг имеет большую площадь и очень близко к кругу, я проверил его следующим образом: len(approx) > 12 and area > 1000 and area < 3000:
. Настройте эту строку в соответствии с вашим сценарием и скажите, решит ли она вашу проблему. Если этого не произойдет, мы можем обсудить более приятные способы или поиграть с этим, чтобы сделать его более точным.