Первый шаг заключается в извлечении зеленого канала из вашего изображения, это легко с OpenCV NumPy и будет производить изображение в градациях серого (2D NUMPY массив)
import numpy as np
import cv2
img = cv2.imread('knots.png')
imgg = img[:,:,1] #extracting green channel
Второй шаг - использование порогового значения, что означает превращение изображения в градациях серого в двоичное (ТОЛЬКО черно-белое) изображение, для которого OpenCV имеет функцию готовности: https://docs.opencv.org/3.4.0/d7/d4d/tutorial_py_thresholding.html
imgt = cv2.threshold(imgg,127,255,cv2.THRESH_BINARY)[1]
Теперь imgt
- это массив 2D numpy
, состоящий исключительно из 0
с и 255
с. Теперь вы должны решить, как вы будете искать места разрезов, я предлагаю следующее:
- верхний ряд пикселей, содержащий не менее 50% от 255 с
- самый нижний ряд пикселей, содержащий не менее 50% от 255 с
- крайний левый столбец пикселя, содержащий не менее 50% от 255 с
- крайний правый столбец пикселя, содержащий не менее 50% от 255 с
Теперь мы должны посчитать количество вхождений в каждом ряду и каждом столбце
height = img.shape[0]
width = img.shape[1]
columns = np.apply_along_axis(np.count_nonzero,0,imgt)
rows = np.apply_along_axis(np.count_nonzero,1,imgt)
Теперь столбцы и строки являются 1D-массивами с номерами, содержащими число 255s
для каждого столбца / строки, зная высоту и ширину, мы можем получить 1D-массивы с bool
значениями следующим образом:
columns = columns>=(height*0.5)
rows = rows>=(width*0.5)
Здесь 0.5
означает 50%, упомянутых ранее, не стесняйтесь настроить это значение в соответствии со своими потребностями Теперь пришло время найти индекс первого True и последнего True в столбцах и строках.
icolumns = np.argwhere(columns)
irows = np.argwhere(rows)
leftcut = int(min(icolumns))
rightcut = int(max(icolumns))
topcut = int(min(irows))
bottomcut = int(max(irows))
Используя argwhere, я получил массивный 1D массив индексов True
с, затем нашел самый низкий и самый большой. Наконец вы можете обрезать свое изображение и сохранить его
imgout = img[topcut:bottomcut,leftcut:rightcut]
cv2.imwrite('out.png',imgout)
Есть два места, которые могут потребовать настройки:% 255
с (в моем примере 50%) и пороговое значение (127
в cv2.threshold
).
РЕДАКТИРОВАТЬ: Фиксированная линия с cv2.threshold