Интенсивное использование np.where
Входящие:
- Подсчет ненулевых пикселей вдоль оси X. Получить y индексы всех строк с хотя бы одним ненулевым пикселем.
- Первый индекс -
ymin
верхней строки. - Последний индекс -
ymax
нижней строки.
- Рассчитать разницу между индексами y (используя
np.diff
) для различения gui sh целые строки (вместо строк). - Первый индекс (сопоставленный с индексами y) -
ymax
верхней строки. - Последний индекс (сопоставленный с индексами y + 1) -
ymin
нижней строки.
- Сосредоточиться на верхней части изображения, получить минимальное и максимальное количество ненулевых пикселей, то есть
xmin
и xmax
верхней линии. - Сосредоточиться на нижней строке image, получите минимальное и максимальное число ненулевых пикселей, то есть
xmin
и xmax
нижней строки.
Это будет код (с использованием Python API):
import cv2
import numpy as np
from skimage import io # Only needed for web reading images
# Web read image; use cv2.imread(...) for local images
img = cv2.cvtColor(io.imread('https://i.stack.imgur.com/S8xJr.jpg'), cv2.COLOR_RGB2BGR)
# Threshold grayscale version of image to get rid of JPG artifacts
img_thr = cv2.threshold(cv2.cvtColor(img, cv2.COLOR_BGR2GRAY), 128, 255, cv2.THRESH_BINARY)[1]
# Determine min/max y values for both lines
y_idx = np.where(np.count_nonzero(img_thr, axis=1))[0]
line1_ymin = y_idx[0]
line2_ymax = y_idx[-1]
thr_inter_line = 10
yy_idx = np.where(np.diff(y_idx) > thr_inter_line)[0]
line1_ymax = y_idx[yy_idx[0]]
line2_ymin = y_idx[yy_idx[-1]+1]
# Determine min/max x values for both lines
line1_xmin = np.min(np.where(img_thr[line1_ymin:line1_ymax, :] == 255)[1])
line1_xmax = np.max(np.where(img_thr[line1_ymin:line1_ymax, :] == 255)[1])
line2_xmin = np.min(np.where(img_thr[line2_ymin:line2_ymax, :] == 255)[1])
line2_xmax = np.max(np.where(img_thr[line2_ymin:line2_ymax, :] == 255)[1])
# Draw rectangles for both lines
img_thr = cv2.rectangle(img_thr, (line1_xmin, line1_ymin), (line1_xmax, line1_ymax), 255, cv2.FILLED)
img_thr = cv2.rectangle(img_thr, (line2_xmin, line2_ymin), (line2_xmax, line2_ymax), 255, cv2.FILLED)
cv2.imshow('img', img)
cv2.imshow('img_thr', img_thr)
cv2.waitKey(0)
cv2.destroyAllWindows()
Это будет вывод:
Надеюсь, это поможет!
----------------------------------------
System information
----------------------------------------
Platform: Windows-10-10.0.16299-SP0
Python: 3.8.1
NumPy: 1.18.1
OpenCV: 4.2.0
----------------------------------------