Вот простой подход с использованием порога + морфологические операции.
Получение двоичного изображения. Загрузка изображения, преобразование в оттенки серого, затем адаптивный порог
Заливка прямоугольников angular контуров. Поиск контуров и заполнение контуров для создания заполненных прямоугольников angular блоков.
Выполните морфинг открытия. Мы создаем прямоугольный angular структурирующий элемент и морфинг открытия, чтобы удалить линии
Рисование прямоугольника. Поиск контуров и рисование ограничивающих прямоугольников .
Вот каждый визуализированный шаг:
Использование этого снимка экрана (содержит больше рамки, поскольку предоставленное изображение имеет прямоугольники слишком близко к границе). Вы можете добавить границу к входному изображению вместо скриншота для большей области границы. Взгляните на добавить рамку к изображению
Двоичное изображение
Заполненный прямоугольник angular контуры
Морфинг открыт
Результат
Код
import cv2
# Load iamge, grayscale, adaptive threshold
image = cv2.imread('1.png')
result = image.copy()
gray = cv2.cvtColor(image,cv2.COLOR_BGR2GRAY)
thresh = cv2.adaptiveThreshold(gray,255,cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY_INV,51,9)
# Fill rectangular contours
cnts = cv2.findContours(thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
cnts = cnts[0] if len(cnts) == 2 else cnts[1]
for c in cnts:
cv2.drawContours(thresh, [c], -1, (255,255,255), -1)
# Morph open
kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (9,9))
opening = cv2.morphologyEx(thresh, cv2.MORPH_OPEN, kernel, iterations=4)
# Draw rectangles
cnts = cv2.findContours(opening, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
cnts = cnts[0] if len(cnts) == 2 else cnts[1]
for c in cnts:
x,y,w,h = cv2.boundingRect(c)
cv2.rectangle(image, (x, y), (x + w, y + h), (36,255,12), 3)
cv2.imshow('thresh', thresh)
cv2.imshow('opening', opening)
cv2.imshow('image', image)
cv2.waitKey()
Примечание: В зависимости от изображения может потребоваться изменить размер ядра. Например, может потребоваться увеличить ядро с (5, 5)
до (11, 11)
. Кроме того, вы можете увеличить или уменьшить количество итераций при выполнении cv2.morphologyEx()
. При увеличении или уменьшении размера ядра существует компромисс, так как вы можете удалить больше или меньше строк. Опять же, все зависит от входного изображения.