В настоящее время существует несколько проблем:
- Если вы посмотрите на свое изображение маски, вы увидите, что все следы красного цвета зафиксированы на маске, включая небольшой шум. В настоящее время вы используете
np.nonzero()
, который захватывает все белые пиксели. Это то, что заставляет ограничивающий прямоугольник покрывать всю область. Чтобы исправить это, мы можем увеличить нижний порог hsv, чтобы получить результирующую маску:
Обратите внимание, что все еще много мелкихсгустки. Ваш вопрос должен быть перефразирован в
Как обрезать большие красные области?
Если вы хотите захватить все красных областей, вы будетеполучить гораздо больше, чем 4 урожая. Таким образом, чтобы исправить это, мы выполним морфологические операции, чтобы удалить небольшой шум и оставить только большие ярко выраженные красные области. Это приводит к маске изображения, которое содержит большие области
Вам не нужно использовать несколько масок
Как получить ограничивающие рамки вокруг каждого красного фрагмента изображения?
Это можно сделать с помощью cv2.findContours()
на изображении маски для возврата ограничивающих прямоугольников каждой красной точки.
О? Это не ваш желаемый результат. Поскольку желаемый результат имеет пространство вокруг каждой красной точки, мы также должны добавить offset
к ограничивающему прямоугольнику. После добавления смещения, вот наш результат
Поскольку у нас есть ограничивающие прямоугольники, мы можем просто использовать срез Numpy для извлечения и сохранения каждого ROI. Вот сохраненные области интереса
Итак, подведем итог, чтобы обнаружить каждое красное пятно на изображении, мы можем использовать пороговое определение цвета HSV. Обратите внимание, что это вернет всех пикселей, которые соответствуют этому пороговому значению, которое может отличаться от ожидаемого, поэтому необходимо выполнить морфологические операции для фильтрации полученной маски. Чтобы получить ограничивающие прямоугольники на каждом красном шарике, мы можем использовать cv2.findContours()
, который даст нам ROI с использованием cv2.boundingRect()
. Как только мы получим ROI, мы добавим смещение и извлечем ROI, используя срез Numpy.
import cv2
import numpy as np
image = cv2.imread("1.png")
original = image.copy()
hsv = cv2.cvtColor(image, cv2.COLOR_BGR2HSV)
hsv_lower = np.array([0,150,50])
hsv_upper = np.array([10,255,255])
mask = cv2.inRange(hsv, hsv_lower, hsv_upper)
kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (3,3))
opening = cv2.morphologyEx(mask, cv2.MORPH_OPEN, kernel, iterations=1)
close = cv2.morphologyEx(opening, cv2.MORPH_CLOSE, kernel, iterations=1)
cnts = cv2.findContours(close, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
cnts = cnts[0] if len(cnts) == 2 else cnts[1]
offset = 20
ROI_number = 0
for c in cnts:
x,y,w,h = cv2.boundingRect(c)
cv2.rectangle(image, (x - offset, y - offset), (x + w + offset, y + h + offset), (36,255,12), 2)
ROI = original[y-offset:y+h+offset, x-offset:x+w+offset]
cv2.imwrite('ROI_{}.png'.format(ROI_number), ROI)
ROI_number += 1
cv2.imshow('mask', mask)
cv2.imshow('close', close)
cv2.imshow('image', image)
cv2.waitKey()