Следующие данные относятся к вашему примеру, хотя может потребоваться настройка для более широкого спектра изображений.
import numpy as np
import cv2
image_src = cv2.imread("input.png")
gray = cv2.cvtColor(image_src, cv2.COLOR_BGR2GRAY)
ret, gray = cv2.threshold(gray, 250,255,0)
image, contours, hierarchy = cv2.findContours(gray, cv2.RETR_LIST, cv2.CHAIN_APPROX_SIMPLE)
largest_area = sorted(contours, key=cv2.contourArea)[-1]
mask = np.zeros(image_src.shape, np.uint8)
cv2.drawContours(mask, [largest_area], 0, (255,255,255,255), -1)
dst = cv2.bitwise_and(image_src, mask)
mask = 255 - mask
roi = cv2.add(dst, mask)
roi_gray = cv2.cvtColor(roi, cv2.COLOR_BGR2GRAY)
ret, gray = cv2.threshold(roi_gray, 250,255,0)
image, contours, hierarchy = cv2.findContours(gray, cv2.RETR_LIST, cv2.CHAIN_APPROX_SIMPLE)
max_x = 0
max_y = 0
min_x = image_src.shape[1]
min_y = image_src.shape[0]
for c in contours:
if 150 < cv2.contourArea(c) < 100000:
x, y, w, h = cv2.boundingRect(c)
min_x = min(x, min_x)
min_y = min(y, min_y)
max_x = max(x+w, max_x)
max_y = max(y+h, max_y)
roi = roi[min_y:max_y, min_x:max_x]
cv2.imwrite("roi.png", roi)
Давать вам следующий тип вывода изображения:
И ...
код работает на первом поиске наибольшую площадь контура. Из этого создается маска, которая используется для первого выбора только области внутри, то есть текста. Затем обратная сторона маски добавляется к изображению для преобразования области вне маски в белый.
Последние контуры найдены снова для этого нового изображения. Любые области контура за пределами подходящего диапазона размеров отбрасываются (это используется для игнорирования любых небольших зон шума), и для каждого из них определяется ограничивающий прямоугольник. С каждым из этих прямоугольников вычисляется ограничивающий прямоугольник для всех оставшихся контуров, и обрезка производится с использованием этих значений для получения окончательного изображения.
Обновления - Чтобы получить оставшуюся часть изображения, то есть с вышеуказанной областью удалены, может быть использовано следующее:
image_src = cv2.imread("input.png")
gray = cv2.cvtColor(image_src, cv2.COLOR_BGR2GRAY)
ret, gray = cv2.threshold(gray, 10, 255,0)
image, contours, hierarchy = cv2.findContours(gray, cv2.RETR_LIST, cv2.CHAIN_APPROX_SIMPLE)
largest_area = sorted(contours, key=cv2.contourArea)[-1]
mask = np.zeros(image_src.shape, np.uint8)
cv2.drawContours(mask, [largest_area], 0, (255,255,255,255), -1)
image_remainder = cv2.bitwise_and(image_src, 255 - mask)
cv2.imwrite("remainder.png", image_remainder)
избирателя, который сказал вопрос слишком-широко. Пожалуйста, дайте мне знать, как сузить его дальше. Я не думаю, что вопрос широк. – Anthony
Вам нужно сделать некоторые адаптивные пороговые значения, а также открыть и закрыть операции. http://docs.opencv.org/doc/tutorials/imgproc/opening_closing_hats/opening_closing_hats.html Вы также можете выполнять обычную эрозию или расширение (что является основным, что делают открытые и закрытые операции). –
Это входное изображение? Или результат какого-то порога? – ZdaR