Python de cero a uno 丨 Lo lleva a comprender el conocimiento teórico y la implementación del dibujo del histograma de imagen

Resumen: este artículo presentará cómo dibujar un histograma a partir de dos aspectos de OpenCV y Matplotlib, que brindarán un soporte efectivo para la comparación de píxeles de procesamiento de imágenes.

Este artículo se comparte desde Huawei Cloud Community " [Python from Zero to One] 50. Mejora y operación de imágenes: conocimiento teórico del histograma de imágenes e implementación del dibujo ", autor: eastmount.

1. Conocimiento teórico del histograma de imagen

El histograma de escala de grises es una función de escala de grises, que describe el número de píxeles de cada escala de grises en la imagen y refleja la frecuencia de cada escala de grises en la imagen. Suponga que hay una imagen de 6 × 6 píxeles y luego cuente la frecuencia de ocurrencia de los niveles de gris 1 a 6 y dibuje un histograma como se muestra en la Figura 1, donde la abscisa indica el nivel de gris y la ordenada indica la ocurrencia de el nivel de gris La frecuencia de [1-2].

Si el nivel de gris es 0-255 (el valor mínimo 0 es negro, el valor máximo 255 es blanco), también se puede dibujar el histograma correspondiente, como se muestra en la Figura 2, la izquierda es una imagen en escala de grises (imagen en escala de grises de Lena), En el la derecha es la frecuencia de escala de grises correspondiente a cada píxel.

Para que la frecuencia de ocurrencia de cada nivel de gris de la imagen forme una forma estándar fija, el histograma de la imagen puede procesarse mediante el método de normalización, y la imagen original a procesar puede convertirse en la forma estándar correspondiente [3] . Suponiendo que la variable r representa el nivel de gris del píxel en la imagen, después del procesamiento de normalización, r se limitará al siguiente rango:

En escala de grises, r=0 significa negro y r=1 significa blanco. Para una imagen dada, cada valor de píxel se ubica en el intervalo [0,1] y luego calcula la distribución de grises de la imagen original, que se realiza mediante la función de densidad de probabilidad P®. Para realizar mejor el procesamiento de imágenes digitales, se deben introducir formas discretas. En la forma discreta, rk se usa para representar el nivel de gris discreto, P(rk) reemplaza a P® y se cumple la fórmula (2).

En la fórmula, nk es el número de píxeles con escala de grises rk en la imagen, n es el número total de píxeles en la imagen, que es la frecuencia en la teoría de probabilidad, y l es el número total de niveles de escala de grises (generalmente l es 256 niveles de escala de grises). Luego haga un diagrama de relación entre rk y P(rk) en el sistema de coordenadas cartesianas, que se convierte en un histograma de nivel de gris [4].

Suponiendo que existe una imagen de 3×3 píxeles cuyos valores de píxeles se muestran en la fórmula (3), los pasos para normalizar el histograma son los siguientes:

En primer lugar, se cuenta el número de píxeles correspondientes a cada nivel de gris. Utilice la matriz x para contar el nivel de gris del píxel y la matriz y para contar la cantidad de píxeles con el nivel de gris. Entre ellos, hay 3 píxeles con una escala de grises de 1, 1 píxel con una escala de grises de 2, 2 píxeles con una escala de grises de 3, 1 píxel con una escala de grises de 4 y 2 píxeles con una escala de grises de 5. individuales.

Luego cuente el número total de píxeles, como se muestra en la fórmula (5).

Finalmente, se cuenta y calcula la probabilidad de ocurrencia de cada nivel de gris mediante la fórmula (6), y los resultados son los siguientes:

El gráfico normalizado dibujado se muestra en la Figura 3, la abscisa indica el nivel de gris de cada píxel en la imagen y la ordenada indica la probabilidad de que aparezca este nivel de gris.

Los histogramas se usan ampliamente en el campo de la visión por computadora.Cuando se usan bordes y colores para determinar los límites de los objetos, los histogramas pueden seleccionar mejor el umbral del límite para la creación de umbrales. Al mismo tiempo, el histograma es particularmente útil para la segmentación de escenas con fuerte contraste entre objetos y fondos, y se puede aplicar para detectar cambios de escena en videos y puntos de interés en imágenes.

2. OpenCV dibuja histograma

Primero, explique cómo usar la biblioteca OpenCV para dibujar un histograma. En OpenCV, puede usar la función calcHist() para calcular el histograma. Después de completar el cálculo, use las funciones de dibujo en OpenCV, como la función rectángulo() para dibujar rectángulos y la función line() para dibujar segmentos de línea . Entre ellos, el prototipo de función y seis parámetros comunes de cv2.calcHist() son los siguientes:

hist = cv2.calcHist(imágenes, canales, máscara, tamaño hist, rangos, acumular)

  • hist representa un histograma y devuelve una matriz bidimensional
  • images representa la imagen original de la entrada
  • canales indica el canal especificado, y el número de canal debe usar corchetes. Cuando la imagen de entrada es una imagen en escala de grises, su valor es [0], y para una imagen en color, es [0], [1], [2 ], que representan azul (B), verde (G), rojo (R)
  • máscara representa una máscara de operación opcional. Si desea contar el histograma de toda la imagen, el valor es Ninguno; si desea contar el histograma de una parte de la imagen, necesita una máscara para calcular
  • histSize representa el número de niveles de gris, necesita usar corchetes, como [256]
  • Los rangos representan el rango de valores de píxeles, como [0, 255]
  • acumular indica el indicador de superposición acumulativa, el valor predeterminado es falso, si se establece en verdadero, el histograma no se borrará al comienzo de la asignación, este parámetro permite que se calcule un único histograma a partir de varios objetos o se use para actualizar el histograma en tiempo real; el resultado acumulativo de varios histogramas se utiliza para el cálculo de histogramas en un conjunto de imágenes

El siguiente código es calcular el tamaño, la forma y la frecuencia de cada nivel de gris de la imagen y luego llamar a la función plot() para dibujar la curva del histograma.

# -*- coding: utf-8 -*-
# By:Eastmount
import cv2  
import numpy as np
import matplotlib.pyplot as plt
import matplotlib
#读取图像
src = cv2.imread('lena-hd.png')
#计算256灰度级的图像直方图
hist = cv2.calcHist([src], [0], None, [256], [0,255])
#输出直方图大小、形状、数量
print(hist.size)
print(hist.shape)
print(hist)
#设置字体
matplotlib.rcParams['font.sans-serif']=['SimHei']
#显示原始图像和绘制的直方图
plt.subplot(121)
plt.imshow(src, 'gray')
plt.axis('off')
plt.title("(a)Lena灰度图像")
plt.subplot(122)
plt.plot(hist, color='r')
plt.xlabel("x")
plt.ylabel("y")
plt.title("(b)直方图曲线")
plt.show()

La curva de histograma correspondiente a la imagen en escala de grises de "Lena" dibujada por el código anterior se muestra en la Figura 4, la Figura 4(a) muestra la imagen original y la Figura 4(b) muestra la curva de histograma en escala de grises correspondiente.

Muestre simultáneamente el tamaño, la forma y la cantidad del histograma, de la siguiente manera:

256
(256L, 1L)
[[7.000e+00]
 [1.000e+00]
 [0.000e+00]
 [6.000e+00]
 [2.000e+00]
 ....
 [1.000e+00]
 [3.000e+00]
 [2.000e+00]
 [1.000e+00]
 [0.000e+00]]

El algoritmo de llamar a OpenCV para dibujar un histograma de una imagen en color es el mismo que el de una imagen en escala de grises, excepto que B, G y R se calculan y dibujan por separado. El código específico es el siguiente.

# -*- coding: utf-8 -*-
# By:Eastmount
import cv2  
import numpy as np
import matplotlib.pyplot as plt
import matplotlib
#读取图像
src = cv2.imread('lena.png')
#转换为RGB图像
img_rgb = cv2.cvtColor(src, cv2.COLOR_BGR2RGB)
#计算直方图
histb = cv2.calcHist([src], [0], None, [256], [0,255])
histg = cv2.calcHist([src], [1], None, [256], [0,255])
histr = cv2.calcHist([src], [2], None, [256], [0,255])
#设置字体
matplotlib.rcParams['font.sans-serif']=['SimHei']
#显示原始图像和绘制的直方图
plt.subplot(121)
plt.imshow(img_rgb, 'gray')
plt.axis('off')
plt.title("(a)Lena原始图像")
plt.subplot(122)
plt.plot(histb, color='b')
plt.plot(histg, color='g')
plt.plot(histr, color='r')
plt.xlabel("x")
plt.ylabel("y")
plt.title("(b)直方图曲线")
plt.show()

La imagen en color dibujada final de "Lena" y su curva de histograma de color correspondiente se muestran en la Figura 5, donde la Figura 5(a) representa la imagen original de Lena, y la Figura 5(b) representa la curva de histograma de color correspondiente.

3. Matplotlib dibuja histogramas

Matplotlib es una poderosa herramienta de visualización de datos para Python, que se utiliza principalmente para dibujar varios gráficos 2D. En esta sección, Python dibuja el histograma principalmente llamando a la función hist() en la biblioteca matplotlib.pyplot, que dibuja el histograma según la fuente de datos y el nivel de píxel. Su función incluye principalmente cinco parámetros de uso común, de la siguiente manera:

n, bandejas, parches = plt.hist(arr, bandejas=50, normalizado=1, color de cara='verde', alfa=0.75)

  • arr representa la matriz unidimensional cuyo histograma debe calcularse
  • bins indica el número de barras que se muestran en el histograma, opcional, el valor predeterminado es 10
  • normed indica si se debe realizar la normalización vectorial sobre el histograma obtenido, el valor por defecto es 0
  • facecolor representa el color del histograma
  • alfa significa transparencia
  • n es el valor devuelto, que representa el vector de histograma
  • bins es el valor devuelto, que indica el rango de intervalo de cada bin
  • parches es el valor de retorno, lo que significa devolver los datos contenidos en cada contenedor, que es una lista

El código de implementación de Python del histograma de la imagen se muestra a continuación. Este ejemplo se dibuja principalmente a través de la función hist() en la biblioteca matplotlib.pyplot. Tenga en cuenta que los píxeles de la imagen leída "lena-hd.png" son matrices bidimensionales, y la fuente de datos de la función hist() debe ser una matriz unidimensional, y la imagen generalmente debe enderezarse a través de la función enmarañar().

# -*- coding: utf-8 -*-
# By:Eastmount
import cv2  
import numpy as np
import matplotlib.pyplot as plt
#读取图像
src = cv2.imread('lena-hd.png')
#绘制直方图
plt.hist(src.ravel(), 256)
plt.xlabel("x")
plt.ylabel("y")
plt.show()
#显示原始图像
cv2.imshow("src", src)
cv2.waitKey(0)
cv2.destroyAllWindows()

La imagen en escala de grises de "lena" que se muestra al leer se muestra en la Figura 6.

El histograma final en escala de grises se muestra en la Figura 7, que dibuja la escala de grises de 256 niveles del mapa de Lena y la frecuencia de cada nivel de escala de grises, donde el eje x representa la escala de grises de 256 niveles de la imagen y el eje y representa la frecuencia de cada nivel de escala de grises.

Si se llama a la siguiente función, el histograma dibujado es un histograma normalizado con un color verde y una transparencia de 0,75, como se muestra en la Figura 8.

plt.hist(src.ravel(), contenedores=256, densidad=1, color de cara='verde', alfa=0.75)

Un histograma de color es un caso especial de un histograma de alta dimensión, que cuenta la frecuencia de cada componente RGB de una imagen en color, es decir, la información de distribución de probabilidad de color. El histograma de la imagen en color es el mismo que el histograma en escala de grises, pero los histogramas de los tres canales se dibujan por separado y luego se superponen.El código es el siguiente. La imagen en color original de Lena se muestra en la Figura 9.

# -*- coding: utf-8 -*-
# By:Eastmount
import cv2  
import numpy as np
import matplotlib.pyplot as plt
#读取图像
src = cv2.imread('Lena.png')
#获取BGR三个通道的像素值
b, g, r = cv2.split(src)
#绘制直方图
plt.figure("Lena")
#蓝色分量
plt.hist(b.ravel(), bins=256, density=1, facecolor='b', edgecolor='b', alpha=0.75)
#绿色分量
plt.hist(g.ravel(), bins=256, density=1, facecolor='g', edgecolor='g', alpha=0.75)
#红色分量
plt.hist(r.ravel(), bins=256, density=1, facecolor='r', edgecolor='r', alpha=0.75)
plt.xlabel("x")
plt.ylabel("y")
plt.show()
#显示原始图像
cv2.imshow("src", src)
cv2.waitKey(0)
cv2.destroyAllWindows()

El histograma de color dibujado se muestra en la Figura 10, incluidos tres contrastes de rojo, verde y azul.

Si desea dibujar y comparar los histogramas de los tres componentes de color por separado, puede usar el siguiente código para lograrlo, llame a la función plt.figure(figsize=(8, 6)) para dibujar la ventana, y plt. función subplot() para dibujar 4 respectivamente un subgrafo.

# -*- coding: utf-8 -*-
# By:Eastmount
import cv2  
import numpy as np
import matplotlib.pyplot as plt
import matplotlib
#读取图像
src = cv2.imread('lena.png')
#转换为RGB图像
img_rgb = cv2.cvtColor(src, cv2.COLOR_BGR2RGB)
#获取BGR三个通道的像素值
b, g, r = cv2.split(src)
print(r,g,b)
plt.figure(figsize=(8, 6))
#设置字体
matplotlib.rcParams['font.sans-serif']=['SimHei']
#原始图像
plt.subplot(221)
plt.imshow(img_rgb)
plt.axis('off')
plt.title("(a)原图像")
#绘制蓝色分量直方图
plt.subplot(222)
plt.hist(b.ravel(), bins=256, density=1, facecolor='b', edgecolor='b', alpha=0.75)
plt.xlabel("x")
plt.ylabel("y")
plt.title("(b)蓝色分量直方图")
#绘制绿色分量直方图
plt.subplot(223)
plt.hist(g.ravel(), bins=256, density=1, facecolor='g', edgecolor='g', alpha=0.75)
plt.xlabel("x")
plt.ylabel("y")
plt.title("(c)绿色分量直方图")
#绘制红色分量直方图
plt.subplot(224)
plt.hist(r.ravel(), bins=256, density=1, facecolor='r', edgecolor='r', alpha=0.75)
plt.xlabel("x")
plt.ylabel("y")
plt.title("(d)红色分量直方图")
plt.show()

El gráfico de salida final se muestra en la Figura 11, la Figura 11(a) muestra la imagen original, la Figura 11(b) muestra el histograma del componente azul, la Figura 11© muestra el histograma del componente verde y la Figura 11(d) muestra la clasificación roja imagen de histograma

Cuatro Resumen

Este artículo explica principalmente el conocimiento teórico de los histogramas de imágenes y los métodos de dibujo de histogramas, e incluye dos métodos estadísticos y de dibujo de Matplotlib y OpenCV. El histograma de escala de grises es una función de escala de grises, que describe el número de píxeles de cada escala de grises en la imagen y refleja la frecuencia de cada escala de grises en la imagen. Los puntos de conocimiento de este artículo brindarán soporte para el procesamiento posterior de imágenes y la comparación de operaciones de imágenes.

referencias:

  • [1] González. Procesamiento de imágenes digitales (3.ª edición) [M]. Beijing: Electronic Industry Press, 2013.
  • [2] Zhang Hengbo, Ou Zongying. Un método de recuperación de imágenes basado en el histograma de color y gris [J]. Ingeniería informática, 2004.
  • [3] Eastmount. [Procesamiento de imágenes digitales] 4. El cuadro de diálogo MFC dibuja un histograma en escala de grises [EB/OL]. (2015-05-31). https://blog.csdn.net/eastmount/article/details/ 46237463.
  • [4] Ruan Qiuqi. Procesamiento de imágenes digitales (3.ª edición) [M]. Beijing: Electronic Industry Press, 2008.
  • [5] Eastmount. [Procesamiento de imágenes de Python] Eleven. El concepto de histograma gris y el histograma de dibujo de OpenCV [EB/OL]. (2018-11-06). https://blog.csdn.net/Eastmount/article /details /83758402.

 

Haga clic para seguir y conocer las nuevas tecnologías de Huawei Cloud por primera vez~

{{o.nombre}}
{{m.nombre}}

Supongo que te gusta

Origin my.oschina.net/u/4526289/blog/8797794
Recomendado
Clasificación