Общая морфологическая функция
В последнем сообщении блога мы представили основные операции эрозии и расширения морфологии, и, комбинируя эрозию и расширение, мы можем реализовать сложные морфологические операции, такие как операции открытия и закрытия.
В OpenCV общая функция морфологии, которую он нам предоставляет, называется cv2.morphologyEx(), и ее полное определение выглядит следующим образом:
def morphologyEx(src, op, kernel, dst=None, anchor=None, iterations=None, borderType=None, borderValue=None):
Эти параметры в основном описаны выше, но необходимо пояснить одну вещь: исходное изображение src должно быть одним из CV_8U, CV_16U, CV_16S, CV_32F и CV_64F.
Конечно, здесь присутствует и незнакомый параметр op, представляющий собой множество морфологических категорий, конкретные категории показаны в таблице:
тип | инструкция | значение | действовать |
---|---|---|---|
cv2.MORPH_ERODE | коррозия | коррозия | erode() |
cv2.MORPH_DILATE | зыбь | зыбь | dilate() |
cv2.MORPH_OPEN | открытая операция | Сначала коррозия, а потом расширение | dilate(erode()) |
cv2.MORPH_CLOSE | закрытая операция | Коррозия после расширения | erode(dilate()) |
cv2.MORPH_GRADIENT | Операция морфологического градиента | Расширение и снижение коррозии | dilate()-erode() |
cv2.MORPH_TOPHAT | операция в цилиндре | Изображение, полученное путем вычитания исходного изображения | src-open() |
cv2.MORPH_BLACKHAT | черные вычисления | Изображение, полученное операцией закрытия, минус исходное изображение | close()-src |
cv2.MORPH_HITMISS | попал промах | Пересечение операций эрозии переднего плана и фона. Поддерживает только двоичные образы CV8UC1. | intersection(erode(src),erode(src1)) |
открытая операция
Как показано в приведенной выше таблице, операция открытия заключается в разрушении исходного изображения и последующем выполнении операции расширения. В основном используется для шумоподавления, подсчета и т. д. Мы выполнили операцию шумоподавления с помощью описанной выше операции эрозии, давайте реализуем интересную операцию подсчета.
import cv2
import numpy as np
img = cv2.imread("open.jpg",cv2.IMREAD_UNCHANGED)
kernel = np.ones((9,9), np.float32)
result = cv2.morphologyEx(img,cv2.MORPH_OPEN,kernel,iterations=5)
cv2.imshow("img", img)
cv2.imshow("result", result)
cv2.waitKey()
cv2.destroyAllWindows()
После запуска мы можем разделить разные области, эффект будет следующим:
закрытая операция
Операция закрытия - это операция, которая расширяет, а затем разъедает. Она помогает закрыть небольшие отверстия в объектах переднего плана или удалить небольшие черные точки на объектах, а также может соединять различные изображения переднего плана. Далее мы свяжем приведенную выше картинку.
import cv2
import numpy as np
img = cv2.imread("close.jpg", cv2.IMREAD_UNCHANGED)
kernel = np.ones((10, 10), np.float32)
result = cv2.morphologyEx(img, cv2.MORPH_CLOSE, kernel, iterations=7)
cv2.imshow("img", img)
cv2.imshow("result", result)
cv2.waitKey()
cv2.destroyAllWindows()
После запуска два блока соединяются как единое целое, и эффект следующий:
Операция морфологического градиента
Операция морфологического градиента - это операция вычитания размытого изображения из расширенного изображения, что позволяет получить край изображения переднего плана в исходном изображении. Мы по-прежнему используем расширенный граф из предыдущей статьи для тестирования, код выглядит следующим образом:
import cv2
import numpy as np
img = cv2.imread("8.jpg", cv2.IMREAD_UNCHANGED)
kernel = np.ones((5, 5), np.float32)
result = cv2.morphologyEx(img, cv2.MORPH_GRADIENT, kernel,iterations=2)
cv2.imshow("img", img)
cv2.imshow("result", result)
cv2.waitKey()
cv2.destroyAllWindows()
После запуска наше изображение пустое, и эффект выглядит следующим образом:
операция в цилиндре
Операция цилиндра — это операция вычитания изображения открытой операции из исходного изображения. Он может получить информацию о шуме изображения или получить информацию о краях, которые ярче, чем края исходного изображения. То есть, чтобы получить белую линию на рисунке выше, конкретный код выглядит следующим образом:
import cv2
import numpy as np
img = cv2.imread("8.jpg", cv2.IMREAD_UNCHANGED)
kernel = np.ones((5, 5), np.float32)
result = cv2.morphologyEx(img, cv2.MORPH_TOPHAT, kernel,iterations=2)
cv2.imshow("img", img)
cv2.imshow("result", result)
cv2.waitKey()
cv2.destroyAllWindows()
После запуска эффект следующий:
черные вычисления
Операция «черная шляпа» — это операция вычитания исходного изображения из изображения закрытой операции. Он может улавливать небольшие отверстия внутри, или маленькие черные точки в цвете переднего плана, или края, которые темнее, чем края исходного изображения. Здесь мы используем предыдущее изображение символа, код выглядит следующим образом:
import cv2
import numpy as np
img = cv2.imread("4.jpg", cv2.IMREAD_UNCHANGED)
kernel = np.ones((5, 5), np.float32)
result = cv2.morphologyEx(img, cv2.MORPH_BLACKHAT, kernel,iterations=2)
cv2.imshow("img", img)
cv2.imshow("result", result)
cv2.waitKey()
cv2.destroyAllWindows()
После запуска эффект следующий:
Функция структурного элемента
Как мы упоминали ранее, элемент структуры может быть настроен или сгенерирован функцией cv2.getStructuringElement(). Вот, давайте взглянем на его полное определение:
def getStructuringElement(shape, ksize, anchor=None):
shape: тип формы, значения следующие:
тип | значение |
---|---|
cv2.MORPH_RECT | Элемент прямоугольной структуры, все элементы имеют значение 1 |
cv2.MORPH_CROSS | Крестообразный структурный элемент со значением диагонального элемента 1 |
cv2.MORPH_ELLIPSE | Овальный структурный элемент |
ksize: размер элемента структуры
привязка: положение привязки элемента структуры, значение по умолчанию (-1, 1), является центром фигуры. Только форма крестообразной звезды тесно связана с положением точки привязки. В других случаях якорная позиция используется только для корректировки результата морфологической операции.
Ниже мы снова реализуем эти три типа фигур, конкретный код выглядит следующим образом:
import cv2
img = cv2.imread("open.jpg", cv2.IMREAD_UNCHANGED)
kernel1 = cv2.getStructuringElement(cv2.MORPH_RECT,(50,50))
kernel2 = cv2.getStructuringElement(cv2.MORPH_CROSS,(50,50))
kernel3 = cv2.getStructuringElement(cv2.MORPH_ELLIPSE,(50,50))
result1 = cv2.dilate(img,kernel1)
result2 = cv2.dilate(img,kernel2)
result3 = cv2.dilate(img,kernel3)
cv2.imshow("img", img)
cv2.imshow("result1", result1)
cv2.imshow("result2", result2)
cv2.imshow("result3", result3)
cv2.waitKey()
cv2.destroyAllWindows()
После запуска эффект следующий: