Это можно сделать с помощью OpenCV, обнаружив зеленые области, а затем выбрав самую большую область. Существует несколько способов обнаружения зеленой зоны, включая cv2.inRange
и cv2.threshold
.
1. Выявление зеленых регионов
cv2.inRange
С помощью inRange
вы можете идентифицировать цвета в определенном диапазоне. Например:
lower_bound = (0,100,0)
upper_bound = (10,255,10)
Таким образом, можно создать пиксели с цветами от lower_bound
до upper_bound
, чтобы создать маску с
mask = cv2.inRange(im, lower_bound, upper_bound)
Вот mask
зеленых зон:
![enter image description here](https://i.stack.imgur.com/Ro9X0.jpg)
cv2.threshold
Точно так же, порог создаст маску зеленых зон. Сначала включите изображение в оттенки серого.
imgray = cv2.cvtColor(im, cv2.COLOR_RGB2GRAY)
![enter image description here](https://i.stack.imgur.com/3PGcS.jpg)
Однако, если вы пороговое значение этого изображения, оно будет определять белые области, поэтому мы хотим, чтобы обратное пороговое значение было найдено в cv2.THRESH_BINARY_INV
ok, thresh = cv2.threshold(imgray, 200, 255, cv2.THRESH_BINARY_INV)
Вот пороговое изображение:
![enter image description here](https://i.stack.imgur.com/exHyx.jpg)
Как видно, thresh
и mask
идентифицируют зеленые области.
2. Контуры
Как только мы получим маску или пороговое изображение, мы можем определить белые области путем поиска контуров. Я буду использовать изображение mask
(можно использовать и thresh
).
(im2, contours, hierarchy) = cv2.findContours(mask, cv2.RETR_EXTERNAL,
cv2.CHAIN_APPROX_SIMPLE)
Мы специально хотим contours
, который дает набор точек, которые можно использовать для выделения зеленых областей. Нам нужен контур, который создает наибольшую площадь контура, которую мы можем найти, сначала расположив их по порядку от наибольшего к наименьшему, а затем выбрав первый.
ordered_cnts = sorted(contours, key=cv2.contourArea, reverse=True)
largest_cnt = ordered_cnts[0]
largest_cnt
- следующий набор точек:
[[[ 0 701]]
[[ 0 999]]
[[298 999]]
[[298 701]]
[[289 701]]
[[288 702]]
[[287 701]]]
Эти точки можно использовать для выделения зеленого поля в левом нижнем углу изображения. Нам нужен только один прямоугольник, чтобы мы могли очертить весь контур, найдя наименьший прямоугольник, который будет окружать все эти точки.
rect = cv2.minAreaRect(largest_cnt)
box = cv2.boxPoints(rect)
box
дает список точек, которые являются четырьмя углами rect
. Мы можем использовать numpy
для преобразования в целочисленные точки и получить пределы поля для обрезки изображения.
box = np.array(box, dtype=int)
x0, y0 = np.min(box,axis=0)
x1, y1 = np.max(box,axis=0)
crop = im[y0:y1, x0:x1]
Изображение crop
:
![enter image description here](https://i.stack.imgur.com/Yfkm5.jpg)
Комбинированный код
lower_bound = (0,100,0)
upper_bound = (10,255,10)
mask = cv2.inRange(im, lower_bound, upper_bound)
(im2, cnts, hierarchy) = cv2.findContours(mask, cv2.RETR_EXTERNAL,
cv2.CHAIN_APPROX_SIMPLE)
ordered_cnts = sorted(cnts, key=cv2.contourArea, reverse=True)
largest_cnt = ordered_cnts[0]
rect = cv2.minAreaRect(largest_cnt)
box = cv2.boxPoints(rect)
box = np.array(box, dtype=int)
x0, y0 = np.min(box,axis=0)
x1, y1 = np.max(box,axis=0)
crop = im[y0:y1, x0:x1]