Первый шаг - извлечь зеленый канал из вашего изображения, это легко с 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
s и 255
s. Теперь вам нужно определиться, как вы будете искать места порезов, предлагаю следующее:
- самая верхняя строка пикселя, содержащая не менее 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)
Теперь столбцы и строки представляют собой одномерные массивы numpy, содержащие количество 255s
для каждого столбца / строки, зная высоту и ширину, мы могли бы получить одномерные массивы numpy значений 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, я получил множество одномерных массивов индексов True
s, а затем нашел самый низкий и самый большой. Наконец, вы можете вырезать изображение и сохранить его.
imgout = img[topcut:bottomcut,leftcut:rightcut]
cv2.imwrite('out.png',imgout)
Есть два места, которые могут потребовать настройки:% от 255
s (в моем примере 50%) и пороговое значение (127
в cv2.threshold
).
РЕДАКТИРОВАТЬ: фиксированная линия с cv2.threshold
person
Daweo
schedule
16.01.2019