El octavo número de python-opencv: explicación detallada de las operaciones de apertura y cierre (Parte 2) (incluidas explicaciones detalladas de las funciones de erosión y dilatación)

Tabla de contenido

descripción general:

Parte del texto:

Principios y funciones:

Análisis de principios:

Pantalla de visualización:

Análisis de funciones:

(1) Operación de corrosión:

(2) Operación de ampliación:

Casos y operaciones:

 (1) Antecedentes de la historia:

 (2) Historia 1 (operación abierta):

 (3) Historia 2 (Operación cerrada):

Conclusión:

Artículo de referencia: 


descripción general:

Como todos sabemos , la visión por computadora (abreviatura de Computer Version  para CV) es una importante dirección de investigación en el desarrollo de la inteligencia artificial y la tecnología robótica en la actualidad , y opencv es una biblioteca de terceros que brinda específicamente soporte técnico y funcional para la programación de visión por computadora. , es naturalmente un contenido en el que hay que centrarse.

En este número, primero hablaremos sobre los principios relevantes y el análisis de funciones de las operaciones de apertura y cierre de imágenes , y demostraremos algunos casos clásicos para su referencia.

Sin más preámbulos, soy Kamen Black , ¡comencemos el estudio de hoy!

Parte del texto:

print("祝大家每天快乐,love and peace!")

Principios y funciones:

——Primer vistazo a la puerta.

Análisis de principios:

De hecho, implementamos operaciones de apertura y cierre principalmente a través de dos maravillosas funciones: dilatar y su hermano erosionar .

Entre ellos, dilatar se utiliza para la expansión morfológica de imágenes , mientras que erosionar se utiliza para la erosión morfológica de imágenes . De manera análoga a nuestra metáfora del número anterior, el efecto de dilatar equivale a un fuerte aguacero , mientras que el efecto de erosionar equivale a una sequía continua .

Es decir:

La función de la visualización dilatada es hacer crecer los píxeles de la imagen hacia afuera para lograr el propósito de aumentar el área;

La función de erosionar la visualización es degradar los píxeles de la imagen hacia adentro para lograr el efecto de reducción de área.

Pero para estudiar en detalle los principios de expansión y corrosión, necesitamos comprender los dos conceptos más críticos: elementos estructurales y puntos de anclaje .

(1) Elemento estructural: equivalente a una máscara (también puede entenderse como una ventana ), puede deslizarse sobre la imagen manipulada y puede seleccionar una parte del marco de píxeles de la imagen manipulada en cada momento . Los elementos estructurales suelen ser rectangulares y pueden variar en largo y ancho.

(2) Punto de anclaje - para elementos estructurales. Como sugiere el nombre, el elemento estructural es como un ancla, el punto que fija el centro de gravedad es la posición de conexión entre el elemento estructural y la imagen manipulada. Por defecto, el punto de anclaje es el punto central de la forma del elemento estructural . El método de selección del punto de anclaje se presentará en el análisis de funciones a continuación.

Después de comprender estos dos conceptos, podemos simplemente explicar los principios operativos de expansión y corrosión ( en lo sucesivo, la imagen operada se denomina A y la imagen operada es B, para evitar textos complicados ):

(1) Erosión: realice el procesamiento de selección de cuadros en un píxel de A y el elemento estructural, es decir, el punto de anclaje del elemento estructural coincide con un píxel de A, y luego observe los píxeles de todos los píxeles de A seleccionados por el marco de máscara del elemento estructural Valor de píxel, tome el valor mínimo como el valor de píxel de este píxel de B. Implemente las operaciones anteriores para cada píxel de A para generar B.

         La expresión de la fórmula es:

 Entre ellos, dst (x, y) representa el valor de píxel del píxel con coordenadas (x, y) en B;

            elemento (x, y) representa el elemento estructural (de hecho, se puede expresar directamente como elemento. El elemento estructural en sí no tiene nada que ver con cada píxel, y (x, y) se agrega solo para hacerlo más vívido);

            (x',y') representa las coordenadas de cada posición en el elemento estructural en relación con el punto de anclaje. Por ejemplo, las coordenadas del punto de anclaje son (0,0), y las coordenadas 2 filas debajo y 3 columnas arriba del punto de anclaje son (2,-3);

            src(x+x',y+y') representa el valor de píxel del píxel con coordenadas (x+x',y+y') en A;

            min significa tomar el valor mínimo.

(2) Expansión: realice un proceso de selección de cuadro en un píxel de A y un elemento estructural, es decir, superponga el punto de anclaje del elemento estructural con un píxel de A, y luego observe los píxeles de todos los píxeles A seleccionados por la máscara. marco del elemento estructural Valor de píxel, tome el valor máximo como el valor de píxel de este píxel de B. Implemente las operaciones anteriores para cada píxel de A para generar B.

         La expresión de la fórmula es:

 Entre ellos, dst (x, y) representa el valor de píxel del píxel con coordenadas (x, y) en B;

            elemento (x, y) representa el elemento estructural (de hecho, se puede expresar directamente como elemento. El elemento estructural en sí no tiene nada que ver con cada píxel, y (x, y) se agrega solo para hacerlo más vívido);

            (x',y') representa las coordenadas de cada posición en el elemento estructural en relación con el punto de anclaje. Por ejemplo, las coordenadas del punto de anclaje son (0,0), y las coordenadas 2 filas debajo y 3 columnas arriba del punto de anclaje son (2,-3);

            src(x+x',y+y') representa el valor de píxel del píxel con coordenadas (x+x',y+y') en A.

            max significa tomar el valor máximo.

Después de comprender el principio de funcionamiento, todavía quedan algunos puntos que deben explicarse brevemente para resolver de antemano las dudas futuras de los lectores:

(1) Método de cálculo de las coordenadas del punto central : si el número de filas y columnas de un elemento estructural es un número impar, entonces el punto central debe ser fácil de encontrar, pero ¿qué pasa si el número de filas o columnas es un número par? En este momento, tome el número de filas como ejemplo. Si el número total de filas de elementos estructurales es un número par, entonces el número de filas donde se encuentra el punto central se puede calcular de la siguiente manera: Número total de filas/2 +1, que es el número de filas donde se ubica el punto central. Lo mismo ocurre con el número de columnas. Nota: Aquí, el primer dígito del número de fila (número de columna) es 1, no 0.

         De hecho, independientemente de si el número de filas (número de columnas) es par o impar, se puede calcular mediante esta fórmula:

  Entre ellos, la función techo significa redondear el operando hacia arriba. Por ejemplo, para operandos en el rango de (2,3], el resultado de la función techo es siempre 3.

(2) El rango de selección del elemento estructural excede la imagen manipulada : el elemento estructural se desliza sobre la imagen manipulada. Si no excede el rango, el valor de píxel de la imagen manipulada se puede calcular de acuerdo con la fórmula. Pero ¿qué pasa si ¿Supera la imagen manipulada? En este momento, hay dos situaciones: una es la situación en la que el límite no se expande y la otra es la situación en la que el límite se expande.

① El caso de límites no expandidos : No consideramos directamente la situación fuera de la imagen operada, solo la situación dentro del rango. Si es una operación de erosión, solo se considera el valor mínimo entre los valores de píxeles enmarcados en la imagen operada; si es una operación de dilatación, solo se considera el valor máximo entre los valores de píxeles enmarcados en la imagen operada.

La situación cuando se expande el límite: si se expande el límite, se debe considerar el valor del límite expandido y la operación se realizará de acuerdo con la situación correspondiente . Por ejemplo, si el tipo de borde expandido (borderType, que se describe a continuación) es cv2.BORDER_CONSTANT, y el valor expandido (borderValue, que también se describe a continuación) es 0, es equivalente a un círculo alrededor de la imagen manipulada. Otro círculo de 0 ( el La magia del amor da vueltas en círculos ). Siempre que la máscara pueda seleccionar el área y esté fuera del rango, el valor de píxel debe mostrarse como 0. Si el valor de expansión es 3, es 3 el que da vueltas una y otra vez.

Pantalla de visualización:

Usar solo palabras puede parecer demasiado abstracto, así que demos una explicación más intuitiva a través de gráficos:

(1) Los elementos estructurales son como se muestra a la derecha: , por defecto el punto de anclaje está en el punto central. Según nuestro método de cálculo de coordenadas del punto central, su punto central está debajo

         La posición de la cruz diagonal en la figura es: .

(2) La imagen operada es como se muestra a la derecha: .

(3) Visualización de imágenes después de las posteriores operaciones de corrosión y expansión:

①Imagen después de la corrosión: ;

②Imagen después de la expansión: .

 Con base en operaciones reales, se puede demostrar que las operaciones de corrosión y expansión morfológicas cumplen con los principios y reglas descritos en este artículo.

Análisis de funciones:

①Preparación para su uso:

Como en números anteriores, todavía llamamos a nuestro antiguo compañero de herramientas ---- opencv como requisito previo para usar rectángulo.

import cv2

②Uso:

Esta parte ya fue explicada en el número anterior, por lo que no la repetiremos aquí.

③ Descripción gramatical:

Hay dos funciones en este número: erosionar y dilatar, que se explican por separado.

(1) Operación de corrosión:

Sintaxis de uso: dst = cv2.erode(src, kernel, dst, ancla, iteraciones, borderType, borderValue)

Descripción del parámetro: El primer dst : la imagen de destino obtenida después de la erosión morfológica a través de la función de erosión, el tipo de datos es tipo de matriz (matriz);

                  src : la imagen de origen procesada usando la función de erosión, el tipo de datos también es un tipo de matriz (matriz);

                  núcleo : el elemento estructural mencionado anteriormente. Los elementos estructurantes se pueden construir mediante la función cv2.getStructuringElement, o mediante las funciones de matriz o unos en la biblioteca numpy. A continuación, hay una breve explicación adicional sobre el uso de la función cv2.getStructuringElement para construir elementos estructurantes:

            Sintaxis de uso: kernel = cv2.getStructuringElement(forma, ksize, ancla)

            Descripción del parámetro: núcleo: el elemento estructural construido mediante la función getStructuringElement;

                              forma: La forma del elemento estructural, con los siguientes valores opcionales: cv2.MORPH_RECT (rectángulo), cv2.MORPH_CROSS (cruz), cv2.MORPH_ELLIPSE (óvalo);

                              ksize: el número de filas y columnas del elemento estructural, el formato del valor es (x, y), donde x representa el número de columnas e y representa el número de filas (esto es contradictorio, tenga en cuenta ) ;

                              anclaje: El punto de anclaje del elemento estructural.Si no toma un valor o si el valor es (-1,-1), se utiliza el punto central del elemento estructural como punto de anclaje. Aquí, solo la forma de máscara de cv2.MORPH_CROSS (forma de cruz) está relacionada con la selección del punto de anclaje. Las otras formas no tienen nada que ver con la selección del punto de anclaje aquí y se pueden seleccionar arbitrariamente.

                  Segundo horario : la descripción es la misma que el primer horario y no se repetirá. El valor predeterminado es Ninguno;

                  anclaje : El punto de anclaje del elemento estructural.Si no toma un valor o si el valor es (-1,-1), el punto central del elemento estructural se utiliza como punto de anclaje. Es diferente del punto de anclaje de la función getStructuringElement. La selección del punto de anclaje aquí afecta los elementos estructurales de todas las formas ;

                  iteraciones : Número de iteraciones. La enésima iteración utiliza el dst de la iteración N-1 como src para la operación, y otros parámetros permanecen sin cambios;

                  borderType : La forma de expandir el borde. El valor predeterminado es Ninguno, lo que significa que no se realiza ninguna expansión del borde. Los tipos específicos se muestran en la siguiente figura:

Fuente de la tabla: el tipo de borderType en opencv , las funciones de erosión y dilatación no admiten el valor del tipo BORDER_WRAP;

                  borderValue : cuando el valor de borderType es cv2.BORDER_CONSTANT, los elementos que extienden el borde se rellenan con borderValue. El valor predeterminado de borderValue es (0, 0, 0). Por supuesto, puede especificar otros valores. Los tres elementos representan BGR respectivamente. Tenga en cuenta que no son RGB.

(2) Operación de ampliación:

Sintaxis de uso: dst = cv2.dilate(src, kernel, dst, ancla, iteraciones, borderType, borderValue)

Descripción del parámetro: Igual que la función de erosión, por lo que no se darán detalles.

Se adjuntan a continuación los documentos nativos relacionados con las funciones de erosionar y dilatar como referencia:

def erode(src: Mat, kernel, dst: Mat = ..., anchor=..., iterations=..., borderType=..., borderValue=...) -> typing.Any:
    '''
    ·"erode(src, kernel[, dst[, anchor[, iterations[, borderType[, borderValue]]]]]) -> dst  
    ·@brief Erodes an image by using a specific structuring element.  

    ·The function erodes the source image using the specified structuring element that determines the  
    ·shape of a pixel neighborhood over which the minimum is taken:

    ·\\f[\\texttt{dst} (x,y) =  \\min _{(x',y'):  \\, \\texttt{element} (x',y') \\ne0 } \\texttt{src} (x+x',y+y')\\f]  

    ·The function supports the in-place mode. Erosion can be applied several ( iterations ) times. In 
    ·case of multi-channel images, each channel is processed independently.

    ·@param src input image; the number of channels can be arbitrary, but the depth should be one of 
    ·CV_8U, CV_16U, CV_16S, CV_32F or CV_64F. 
    ·@param dst output image of the same size and type as src.  
    ·@param kernel structuring element used for erosion; if `element=Mat()`, a `3 x 3` rectangular
    ·structuring element is used. Kernel can be created using #getStructuringElement.  
    ·@param anchor position of the anchor within the element; default value (-1, -1) means that the 
    ·anchor is at the element center.   
    ·@param iterations number of times erosion is applied.   
    ·@param borderType pixel extrapolation method, see #BorderTypes. #BORDER_WRAP is not supported. 
    ·@param borderValue border value in case of a constant border   
    ·@sa  dilate, morphologyEx, getStructuringElement"
    ...
    '''
def dilate(src: Mat, kernel, dst: Mat = ..., anchor=..., iterations=..., borderType=..., borderValue=...) -> typing.Any:
    '''
    ·"dilate(src, kernel[, dst[, anchor[, iterations[, borderType[, borderValue]]]]]) -> dst 
    ·@brief Dilates an image by using a specific structuring element.      

    ·The function dilates the source image using the specified structuring element that determines the   
    ·shape of a pixel neighborhood over which the maximum is taken:  
    ·\\f[\\texttt{dst} (x,y) =  \\max _{(x',y'):  \\, \\texttt{element} (x',y') \\ne0 } \\texttt{src} (x+x',y+y')\\f]   

    ·The function supports the in-place mode. Dilation can be applied several ( iterations ) times. In   
    ·case of multi-channel images, each channel is processed independently.   

    ·@param src input image; the number of channels can be arbitrary, but the depth should be one of  
    ·CV_8U, CV_16U, CV_16S, CV_32F or CV_64F.   
    ·@param dst output image of the same size and type as src.   
    ·@param kernel structuring element used for dilation; if elemenat=Mat(), a 3 x 3 rectangular   
    ·structuring element is used. Kernel can be created using #getStructuringElement\n.   
    ·@param anchor position of the anchor within the element; default value (-1, -1) means that the
    ·anchor is at the element center.   
    ·@param iterations number of times dilation is applied.   
    ·@param borderType pixel extrapolation method, see #BorderTypes. #BORDER_WRAP is not suported.\   
    ·@param borderValue border value in case of a constant border  
    ·@sa  erode, morphologyEx, getStructuringElement"
    ...
    '''

Casos y operaciones:

- -Picadora de pequeña escala

A continuación, seguiremos utilizando el pequeño incidente entre los dos lagos del número anterior como nuestra operación de caso:

(1) Antecedentes de la historia:

        Se dice que hace mucho, mucho tiempo, había dos lagos, estaban muy cerca uno del otro, apoyados el uno en el otro como amantes, y había un pequeño río en el medio que los conectaba como un vínculo entre ellos. La gente cercana llama a uno de ellos lago Tiezhu , al otro Cuihua Po , y el pequeño río en el medio se llama río Qingshou , porque son como dos pequeños lagos tomados de la mano. Días como este, después de mucho tiempo, parecen seguir así. . . (Ya sabes lo que voy a decir a continuación :))

Lago Tiezhu y Cuihua Po

 (2) Historia 1 (operación abierta):

        Pero a medida que el tiempo pasó así durante mucho tiempo, era como una persona que sufría la picazón de los siete años, y a los dos lagos les empezó a desagradar la compañía constante del otro. Entonces se quejaron ante Dios, con la esperanza de separarlos a los dos, con la esperanza de darse espacio para vivir sus propias vidas. Dios escuchó sus súplicas y dijo que sí, pero deben aceptar la prueba, que es una sequía duradera que cortará el río que los separa y evaporará sus propios lagos.

        Los dos lagos llevaban mucho tiempo hartos el uno del otro, por lo que ambos aceptaron la prueba sin decir nada. Pronto llegó la sequía, al principio los dos lagos eran aceptables, pero sintieron que su capacidad se había reducido un poco. Pero más tarde, la sequía todavía tuvo un gran impacto: debido a la sequía que duró todo el día, las plantas continuaron muriendo, los animales también buscaron otros lugares para vivir y los aldeanos que vivían allí gradualmente abandonaron este triste lugar. Finalmente, el río Lian Shou se evaporó por completo y los dos lagos quedaron completamente separados. Pero el entorno circundante ya está en ruinas y el lago ha perdido su vitalidad. El lago Tiezhu y Cuihua Po también comenzaron a recordar el tiempo pasado, que comparado con este tiempo era extremadamente brillante y hermoso.

        Poco a poco fue pasando el tiempo, la sequía terminó y llegó la temporada de lluvias. A medida que el agua de lluvia seguía cayendo, el área de los dos lagos comenzó a expandirse lentamente y la esperanza de interconexión comenzó a surgir en sus corazones. Sin embargo, con el final de la temporada de lluvias, los dos lagos sólo se han recuperado aproximadamente en el mismo área que antes, pero aún no están conectados entre sí. El lecho del río Hands-Hand se ha convertido desde hace mucho tiempo en un terreno elevado insuperable entre los dos. 

import cv2
import numpy as np

img = cv2.imread("F://src.jpg")

kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE,(10,10))

img1 = cv2.erode(img,kernel,iterations=2)
img2 = cv2.dilate(img1,kernel,iterations=3)

cv2.imwrite("F://rst1.jpg",img2)

cv2.imshow("src",img)
cv2.imshow("rst1",img2)
cv2.waitKey(5000)
cv2.destroyAllWindows()
Dos lagos separados entre sí

 

 (3) Historia 2 (Operación cerrada):

        Los dos lagos volvieron a orar a Dios, con la esperanza de conectarlos nuevamente. Dios respondió, si realmente quieren hacer esto, pueden cumplir tu deseo esta vez, pero todavía hay una condición, es decir, esta vez no solo estás conectado por un río que te toma de la mano, sino una integración completa. lago para lograr una situación en la que tú estás en mí y yo en ti. Y este es el último deseo, una vez que se conviertan en uno, nunca podrán volver a separarse.

        Esta vez ni Tiezhu ni Cuihua llegaron a una conclusión inmediata, ambos pensaron y deliberaron durante mucho tiempo. Finalmente le dijeron a Dios su elección: ambos querían ser uno. Dios dice que sí y concederá tus deseos. Luego llovió mucho. La lluvia no sólo fue intensa, sino también duradera: fue tan prolongada que el lecho del río Hand-Hand se volvió a llenar de agua y siguió expandiéndose. La lluvia fue demasiado intensa y el entorno volvió a ser inadecuado para la supervivencia de animales y plantas. El área alrededor del lago volvió a quedar sin rastros de vida. Pero esta vez los dos lagos no tuvieron quejas y decidieron aceptarlo. en silencio, apoyarnos unos a otros y permanecer juntos hasta el último momento. .

        Finalmente, la lluvia paró y apareció el sol, provocando ondas en el lago que se había fusionado en uno. Con el final de la temporada de lluvias, el área del lago volvió lentamente a su tamaño normal, pero desde entonces nunca se ha separado. Más tarde, la gente supo que había dos lagos fusionados en uno, pero ya no recordaban los nombres de los dos lagos, solo sabían que había un lago llamado Hexinhai . Cada año, muchas parejas vienen aquí a orar, con la esperanza de que su amor mutuo sea como el origen de Hexinhai.Aunque han pasado por todo tipo de dificultades, nunca se dejarán cuando regresen y pasarán su tiempo. días juntos.

import cv2
import numpy as np

img = cv2.imread("F://rst1.jpg")

kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE,(10,10),anchor=(0,0))

img1 = cv2.dilate(img,kernel,iterations=6)
img2 = cv2.erode(img1,kernel,iterations=3)

cv2.imwrite("F://rst2.jpg",img2)

cv2.imshow("rst1",img)
cv2.imshow("rst2",img2)
cv2.waitKey(5000)
cv2.destroyAllWindows()
hexinhai

 

        Creo que el amor más preciado no es el amor a primera vista, sino la lealtad y la responsabilidad mutua que aún puede brillar a través de las olas y la arena. Sólo las perlas que han pasado la prueba del viento, las heladas y la deposición del tiempo pueden convertirse en perlas brillantes y translúcidas. Como dice la inscripción "Lema" escrita por Cui Yuan de la dinastía Han del Este: " En el nirvana no hay zi y hay luz en el calor " .

Conclusión:

En este artículo, aprendimos sobre los principios básicos de expansión y corrosión , y también aprendimos algunos puntos a los que debemos prestar atención durante la operación, como el método de cálculo de las coordenadas del punto central, varias situaciones en las que la selección del marco de elementos estructurales excede imágenes manipuladas, etc., aprendimos el significado y el método de configuración de cada parámetro en las funciones de erosionar y dilatar . Finalmente, utilizamos una hermosa ( anticuada ) historia de amor como fondo para demostrar casos reales de operaciones de apertura y cierre . En general, el contenido de este número es bastante sustancial y espero que todos puedan adquirir conocimientos y ser felices.

 Bien, ese es todo el contenido anterior. Espero que puedas prestar más atención , darle me gusta y recopilarlo . Esto será de gran ayuda para mí. ¡Gracias a todos!

  Bien, este es Kamen Black . Les deseo paz y prosperidad, ¡nos vemos a todos la próxima vez! ! ! Yoyo~~

Artículo de referencia: 

Procesamiento de imágenes OpenCV-Python: principios de corrosión y expansión e introducción a las funciones de erosionar y dilatar

Supongo que te gusta

Origin blog.csdn.net/m0_55320151/article/details/132015619
Recomendado
Clasificación