OpenCV 09 (morfología)

1. Morfología

La morfología se refiere a una serie de técnicas de procesamiento de imágenes que se ocupan de las características de forma de las imágenes.

  • La idea básica de la morfología es utilizar un elemento estructural especial (esencialmente un núcleo de convolución) para medir o extraer la forma o característica correspondiente en la imagen de entrada para un mayor análisis de la imagen y reconocimiento de objetivos.
  • Estos métodos de procesamiento básicamente procesan imágenes binarias , es decir, imágenes en blanco y negro.
  • El núcleo de convolución determina el efecto del procesamiento de imágenes.


Las operaciones básicas comúnmente utilizadas en morfología son:

    - Expansión y corrosión
    - Operaciones de apertura
    - Operaciones de cierre
    - Sombrero de copa
    - Sombrero negro

1.1 Binarización global de imágenes 

Binarización: convierta cada píxel de la imagen en dos valores, como 0, 255

0 y 255: 0 es negro y 255 es blanco

01: 0 es negro, 1 es blanco

- umbral(src, umbral, maxval, tipo[, dst])

  - src es preferiblemente una imagen en escala de grises

  - umbral: umbral

  - maxval: valor máximo, el valor máximo no es necesariamente 255

  - tipo: tipo de operación. Los tipos de operación comunes son los siguientes:

 import cv2
  import numpy as np
  
  img = cv2.imread('./dog.jpeg')
  
  gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
  
  # 返回两个结果, 一个是阈值, 另一个是处理后的图片
  ret, dst = cv2.threshold(gray, 80, 255, cv2.THRESH_BINARY)
  
  cv2.imshow('dog', np.hstack((gray, dst)))
  
  cv2.waitKey(0)
  cv2.destroyAllWindows()

1.2 Binarización de umbral adaptativo

En la parte anterior usamos un umbral global, usando el mismo número que el umbral para toda la imagen . Este método no es adecuado para todas las situaciones, especialmente cuando diferentes partes de la misma imagen tienen diferente brillo. En este caso necesitamos utilizar un umbral adaptativo . El umbral en este momento es calcular el umbral correspondiente en función de cada área pequeña de la imagen. Por tanto, se utilizan diferentes umbrales en diferentes zonas de una misma imagen , permitiéndonos obtener mejores resultados cuando el brillo es diferente.

adaptiveThreshold(src, maxValue, adaptiveMethod, umbralType, blockSize, C, dst=None)**
 Este método requiere que especifiquemos seis parámetros y solo devuelve un valor.

 • **Método adaptativo**: especifica el método utilizado para calcular el umbral.
 – **cv2.ADPTIVE_THRESH_GAUSSIAN_C**: el umbral se toma del valor promedio de áreas adyacentes
 – **cv2.ADPTIVE_THRESH_GAUSSIAN_C**: el umbral se toma de la suma ponderada de áreas adyacentes y el peso es una ventana gaussiana. 
 • **Tamaño de bloque**: tamaño del vecindario (tamaño de la región utilizada para calcular el umbral).
 • **C**: es una constante y el umbral es igual al promedio o al promedio ponderado menos esta constante.

# 因为光线问题, 全局二值化导致有部分地方看不见了.这时就需要自适应阈值二值化了.
import cv2
import numpy as np

img = cv2.imread('./math.png')

cv2.namedWindow('img', cv2.WINDOW_NORMAL)
cv2.resizeWindow('img', 1920, 1080)

gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

# 自适应阈值二值化只返回一个值, 即二值化后的结果
dst = cv2.adaptiveThreshold(gray, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY_INV, 3, 0)

cv2.imshow('img', np.hstack((gray, dst)))

cv2.waitKey(0)
cv2.destroyAllWindows()

 

1.3 Operaciones de corrosión

 La operación de corrosión también utiliza un núcleo de convolución para escanear la imagen, pero el núcleo de convolución de la operación de corrosión es generalmente 1. Si todos los píxeles del núcleo de convolución son blancos, entonces el punto de anclaje es blanco. 

- La mayoría de las veces, la operación de corrosión utiliza un núcleo de convolución de todo 1.

- erosionar(src, kernel[, dst[, ancla[, iteraciones[, borderType[, borderValue]]]]])

  - iteraciones es el número de iteraciones de la operación de corrosión. Cuanto mayor es el número, más veces se realiza la operación de corrosión y más obvio es el efecto de la corrosión.

import cv2
import numpy as np

img = cv2.imread('./msb.png')

kernel = np.ones((3, 3), np.uint8)

dst = cv2.erode(img, kernel, iterations=2)

cv2.imshow('img', np.hstack((img, dst)))

cv2.waitKey(0)
cv2.destroyAllWindows()

 

 

1.4 Obtener el núcleo de convolución morfológico

- opencv proporciona una API para obtener núcleos de convolución. No necesitamos crear núcleos de convolución manualmente.
- getStructuringElement(shape, ksize[, Anchor])

  - La forma se refiere a la forma del núcleo de convolución. Tenga en cuenta que no se refiere a la longitud y el ancho, sino que se refiere a la forma formada por el 1 en el núcleo de convolución. - MORPH_RECT El 1 en el núcleo de convolución es un rectángulo,
    que se usa comúnmente
    - MORPH_ELLIPSE elipse
    - MORPH_CROSS cruz

import cv2
import numpy as np

img = cv2.imread('./j.png')

kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (3, 3))
dst = cv2.erode(img, kernel, iterations=2)

cv2.imshow('img', np.hstack((img, dst)))

cv2.waitKey(0)
cv2.destroyAllWindows()

1.5 Operación de expansión

La dilatación es la operación opuesta a la erosión. El principio básico es que siempre que se garantice que el punto de anclaje del núcleo de convolución sea un valor distinto de cero, los valores circundantes se convertirán en valores distintos de cero, ya sean 0 o valores distintos de cero.

- dilatar(img, kernel, iteraciones=1)

import cv2
import numpy as np

img = cv2.imread('./j.png')

kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (3, 3))
dst = cv2.dilate(img, kernel, iterations=2)

cv2.imshow('img', np.hstack((img, dst)))

cv2.waitKey(0)
cv2.destroyAllWindows()

 

1.6 Operación abierta

 Las operaciones de apertura y cierre son aplicaciones básicas de erosión y dilatación. 

- Operación abierta = erosión + expansión
- morfologíaEx(img, MORPH_OPEN, kernel)

  - MORPH_OPEN representa la operación de apertura morfológica
  - kernel Si hay más puntos de ruido, se seleccionará un kernel más grande. Si los puntos de ruido son más pequeños, se puede seleccionar un kernel más pequeño.

import cv2
import numpy as np

img = cv2.imread('./dotj.png')

kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (5, 5))

# 腐蚀
# dst = cv2.erode(img, kernel, iterations=2)

# # 膨胀
# dst = cv2.dilate(dst, kernel, iterations=2)

# 直接调用opencv提供的开运算api
dst = cv2.morphologyEx(img, cv2.MORPH_OPEN, kernel, iterations=2)

cv2.imshow('img', np.hstack((img, dst)))

cv2.waitKey(0)
cv2.destroyAllWindows()

1.7 Operaciones cerradas

- Operación cerrada = dilatación + corrosión

import cv2
import numpy as np

img = cv2.imread('./dotinj.png')

kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (5, 5))

dst = cv2.morphologyEx(img, cv2.MORPH_CLOSE, kernel, iterations=2)

cv2.imshow('img', np.hstack((img, dst)))

cv2.waitKey(0)
cv2.destroyAllWindows()

1.8 gradiente morfológico

- Degradado = Imagen original - Corrosión
- Después de la corrosión, el borde de la imagen original se vuelve más pequeño Imagen original - La corrosión puede corroer la parte, es decir, el borde.

import cv2
import numpy as np

img = cv2.imread('./j.png')

# 注意调节kernel大小以获得更清晰的边缘
kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (3, 3))

dst = cv2.morphologyEx(img, cv2.MORPH_GRADIENT, kernel, iterations=1)

cv2.imshow('img', np.hstack((img, dst)))

cv2.waitKey(0)
cv2.destroyAllWindows()

1.9 Operación del sombrero de copa

- Sombrero de copa = imagen original - Operación de apertura
- El efecto de la operación de apertura es eliminar el ruido fuera de la imagen Imagen original - La operación de apertura obtendrá el ruido eliminado.

import cv2
import numpy as np

img = cv2.imread('./tophat.png')

# 注意调整kernel以保留小图形
kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (19, 19))

dst = cv2.morphologyEx(img, cv2.MORPH_TOPHAT, kernel, iterations=1)

cv2.imshow('img', np.hstack((img, dst)))

cv2.waitKey(0)
cv2.destroyAllWindows()

 

1.10 Operación de sombrero negro

- Sombrero negro = imagen original - operación cerrada
- la operación cerrada puede eliminar el ruido dentro del gráfico, luego el resultado de la imagen original - operación cerrada es el ruido dentro del gráfico.

import cv2
import numpy as np

img = cv2.imread('./dotinj.png')

# 注意调节kernel大小以获得更清晰的边缘
kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (7, 7))

dst = cv2.morphologyEx(img, cv2.MORPH_BLACKHAT, kernel, iterations=1)

cv2.imshow('img', np.hstack((img, dst)))

cv2.waitKey(0)
cv2.destroyAllWindows()

Supongo que te gusta

Origin blog.csdn.net/peng_258/article/details/132774908
Recomendado
Clasificación