Procesamiento de imágenes de Python: segmentación de imágenes y segmentación de imágenes basada en colores de casos clásicos

En el prefacio,
el autor introduce los conocimientos básicos del procesamiento de imágenes en la primera parte, la segunda parte introduce la computación de imágenes y la mejora de imágenes, a continuación, en la tercera parte, explicaremos en detalle los casos clásicos de segmentación de imágenes y procesamiento de imágenes. Esta parte pertenece al procesamiento de imágenes de alto nivel. El conocimiento puede profundizar aún más nuestra comprensión y capacidad práctica. La segmentación de imágenes es la tecnología y el proceso de dividir una imagen en varias regiones con propiedades únicas y extraer objetos de interés. Es un paso clave en el procesamiento y análisis de imágenes. Se divide principalmente en métodos de segmentación basados ​​en umbrales, métodos de segmentación basados ​​en regiones, métodos de segmentación basados ​​en bordes y métodos de segmentación basados ​​en teorías específicas. Este artículo explicará en detalle el método de segmentación de imágenes basado en colores.

1. Segmentación de imágenes basada en colores

La segmentación del color es una tecnología importante en el procesamiento de imágenes, ya que puede separar diferentes colores en una imagen para escenarios de aplicaciones como la detección de objetivos y el reconocimiento de imágenes.

El principio del algoritmo de segmentación del color es relativamente simple y, por lo general, se realiza en función de la transformación del espacio de color. Los espacios de color comúnmente utilizados incluyen RGB, HSV, LAB, etc., entre los cuales el espacio de color HSV es más adecuado para tareas de segmentación de color. El espacio de color HSV divide los colores en tres canales: tono, saturación y valor.

  • Matiz: Indica el tipo o tipo de color, como rojo, azul, verde, etc.
  • Saturación: Indica la pureza del color, cuanto más saturado es el color, más vivo es, y viceversa.
  • Brillo: Se refiere a la luminosidad y oscuridad de un color. En color, cuanto mayor es el brillo, más brillante es el color; cuanto menor es el brillo, más oscuro es el color.

La idea básica de la segmentación de color es segmentar píxeles de diferentes colores mediante umbralización. Específicamente, podemos convertir la imagen del espacio de color RGB al espacio de color HSV y luego seleccionar un umbral apropiado (generalmente los valores máximo y mínimo de tono, saturación y brillo) para dividir la imagen en partes en blanco y negro. .

En espacio de color opencv hsv

  • El valor máximo de tono (Hue) es de 179 grados y el valor mínimo es de 0 grados, lo que representa la posición del color en la rueda de colores.

  • El valor máximo de Saturación es 255 y el valor mínimo es 0, lo que representa la pureza y la escala de grises del color.

  • El valor máximo de Brillo es 255 y el valor mínimo es 0, lo que representa la claridad y la oscuridad del color.

Pasos de implementación
Según los principios del algoritmo anterior, podemos realizar los siguientes pasos para lograr la segmentación de color:

  1. Convierta una imagen del espacio de color RGB al espacio de color HSV.
  2. Calcular los valores máximos y mínimos de Tono, Saturación, Brillo respectivamente
  3. Establezca el umbral para dividir la imagen en partes en blanco y negro.
  4. Utilice operaciones morfológicas para eliminar el ruido y obtener el resultado de segmentación final.

Este documento utiliza la función cv2.inRange() en OpenCV para realizar una segmentación basada en el color del objetivo en la imagen.

máscara = cv2.inRange(src, lowerb, upperb[, dst])

— El parámetro src es la imagen de entrada, que puede ser de un solo canal o multicanal, y el tipo de datos es np.uint8
— mask es la imagen de salida, que es una imagen de un solo canal (imagen binaria), y los datos type es el mismo que la imagen de entrada
— lowerb es el límite inferior especificado, de tipo Scalar, que puede ser un valor único, una tupla o una lista de valores múltiples
—upperb es el límite superior especificado, de tipo Scalar, que puede ser un valor único o una tupla o lista de múltiples valores

Nota:
La máscara representa la información de posición de los píxeles que coinciden con el rango de color especificado, es decir, el valor de píxel correspondiente de los píxeles dentro del rango de color especificado en la imagen binaria es 255, y los píxeles que no están en el rango de color especificado están en la imagen binaria El valor de píxel correspondiente en es 0. Por lo tanto, al usar esta máscara, podemos operar selectivamente en la imagen y solo procesar píxeles dentro del rango de color especificado sin afectar a otros píxeles.

El siguiente es un código de segmentación de color simple basado en el principio del algoritmo anterior (la máscara en sí proporciona un rango determinado):

import cv2
import numpy as np

# 读入图片
img = cv2.imread( "C:/Users/Administrator/Desktop/flower.png")

# 转换颜色空间
hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)

# 定义绿色范围
lower_green = np.array([40, 50, 50])
upper_green = np.array([90, 255, 255])

# 定义黄色范围
lower_yellow = np.array([15, 50, 50])
upper_yellow = np.array([40, 255, 255])

# 根据颜色范围创建掩码
mask_green = cv2.inRange(hsv, lower_green, upper_green)
mask_yellow = cv2.inRange(hsv, lower_yellow, upper_yellow)

# 合并掩码
mask = cv2.bitwise_or(mask_green, mask_yellow)

# 应用掩码
result = cv2.bitwise_and(img, img, mask=mask)

# 显示结果
cv2.imshow('result', result)
cv2.waitKey(0)
cv2.destroyAllWindows()

Los resultados de la ejecución se muestran en la Figura 1-1. Los girasoles están bien segmentados en la figura, pero la hierba también está segmentada.
inserte la descripción de la imagen aquí
Los siguientes son los rangos de HSV de algunos colores comunes:

Rojo: (0, 70, 50) - (10, 255, 255) o (170, 70, 50) - (179, 255, 255)

Naranja: (10, 70, 50) - (25, 255, 255)

Amarillo: (25, 70, 50) - (35, 255, 255)

Verde: (35, 70, 50) - (85, 255, 255)

Cian: (85, 70, 50) - (100, 255, 255)

Azul: (100, 70, 50) - (130, 255, 255)

Púrpura: (130, 70, 50) - (170, 255, 255)

Blanco: (0, 0, 221) - (180, 30, 255)

Negro: (0, 0, 0) - (180, 255, 30)

2. Determine el rango de valores de color observando el histograma

Cuando el objetivo de color que se va a segmentar no tiene una interferencia importante en la imagen, el rango de valores del objetivo de color se puede determinar observando el histograma del componente de matiz (Tono), como estándar límite para nuestra segmentación.

El ejemplo de código es el siguiente:

import cv2
import numpy as np
from matplotlib import pyplot as plt

#通过OpenCV读取图片信息
img = cv2.imread("C:/Users/Administrator/Desktop/scenery.jpg")
# BGR图转为HSV
hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
# 提取hsv中H通道数据
h = hsv[:, :, 0].ravel()
# 直方图显示
plt.hist(h, 180, [0, 180])
plt.show()

Obtenga el histograma, como se muestra en la Figura 2-1:
inserte la descripción de la imagen aquí
De acuerdo con el rango HSV de colores comunes mencionados en la apelación, aparece una gran cantidad de datos en la parte 30 a 70 del histograma, por lo que se puede determinar que la parte superior y los límites inferiores del componente H verde son 30-70. El límite de SV se puede establecer aproximadamente de acuerdo con el rango de HSV propuesto en la apelación, y se puede ajustar y determinar al extraer la máscara

La máscara de máscara se genera debajo a través del límite verde de HSV. el código se muestra a continuación:

import cv2
import numpy as np
from matplotlib import pyplot as plt

#通过OpenCV读取图片信息
img = cv2.imread("C:/Users/Administrator/Desktop/scenery.jpg")
hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)

# HSV 的下界限
lower_red = np.array([35,70,50])
# HSV 的上界限
upper_red = np.array([70,255,255])

# 通过上下限提取范围内的掩模mask
mask = cv2.inRange(hsv, lower_red, upper_red)

img =  cv2.resize(img,(500,500))
mask = cv2.resize(mask,(500,500))

cv2.imshow("img", img)
cv2.imshow("mask", mask)
cv2.waitKey(0)
cv2.destroyAllWindows()

El resultado de la ejecución se muestra en la Figura 2-2
inserte la descripción de la imagen aquí

Se puede encontrar que se ha extraído el contorno general de la hierba, pero hay muchos puntos negros en el campo.Esto se debe a que la mayoría de los puntos negros están en la oscuridad, y podemos filtrarlos reduciendo el límite inferior de el valor V. Aquí, el límite inferior del valor V está determinado por El 50 original se ajusta a 15

El efecto es el siguiente:
inserte la descripción de la imagen aquí
en este momento, algunos puntos negros no se pueden eliminar mediante el ajuste de V, podemos usar expansión, corrosión y otros medios para eliminar puntos blancos o negros independientes.

El código para eliminar los puntos negros es el siguiente:

import cv2
import numpy as np
from matplotlib import pyplot as plt

#通过OpenCV读取图片信息
img = cv2.imread("C:/Users/Administrator/Desktop/scenery.jpg")
hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)

# HSV 的下界限
lower_green = np.array([35,70,15])
# HSV 的上界限
upper_green = np.array([70,255,255])

# 通过上下限提取范围内的掩模mask
mask = cv2.inRange(hsv, lower_green, upper_green)

# 定义结构元素
kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (5, 35))
# 图像闭运算
mask = cv2.morphologyEx(mask, cv2.MORPH_CLOSE, kernel, iterations=2)

img =  cv2.resize(img,(500,500))
mask = cv2.resize(mask,(500,500))

cv2.imshow("img", img)
cv2.imshow("mask", mask)
cv2.waitKey(0)
cv2.destroyAllWindows()

El efecto se muestra en la Figura 2-3
inserte la descripción de la imagen aquí
Se puede ver que los puntos negros se eliminan, y luego usamos cv2.bitwise_and() para bit a bit y la imagen original y la máscara para extraer la imagen de la hierba:
inserte la descripción de la imagen aquí

reemplazo de color

A través de las operaciones anteriores, ya podemos segmentar con precisión el color que especificamos, y luego podemos cambiar su color en una segunda base, como cambiarlo a amarillo. Esto también debe operarse en el espacio de color HSV, pero esta vez hay No es necesario realizar una operación de cierre en la máscara.

Use la función createTrackbar para ajustar hsv aquí

cv2.createTrackbar(trackbarName, windowName, value, count, onChange)

  • trackbarName: el nombre de la barra arrastrable, tipo cadena.
  • windowName: El nombre de la ventana donde se encuentra la barra arrastrable, tipo string.
  • valor: el valor predeterminado de la barra arrastrable, entero.
  • count: el valor máximo de la barra arrastrable, entero.
  • onChange: la función de devolución de llamada llamada cuando cambia el valor de la barra arrastrable, tipo de función.

el código se muestra a continuación:

import cv2
import numpy as np

def nothing(x):
    pass
#通过OpenCV读取图片信息
img = cv2.imread("C:/Users/Administrator/Desktop/scenery.jpg")

img = cv2.resize(img,(500,500))
cv2.namedWindow('img',cv2.WINDOW_NORMAL)
cv2.imshow("img", img)

# HSV 的下界限
lower_green = np.array([35,70,15])
# HSV 的上界限
upper_green = np.array([70,255,255])

cv2.namedWindow('img2',cv2.WINDOW_NORMAL)

cv2.createTrackbar('H','img2',140,180,nothing)
cv2.createTrackbar('S','img2',100,180,nothing)
cv2.createTrackbar('V','img2',117,180,nothing)
rows,cols,channels = img.shape

while(1):
    hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
    mask = cv2.inRange(hsv, lower_green, upper_green)
    #将制定像素点的数据设置为0, 要注意的是这三个参数对应的值是Blue, Green, Red。
    h = cv2.getTrackbarPos('H', 'img2')
    s = cv2.getTrackbarPos('S', 'img2')
    v = cv2.getTrackbarPos('V', 'img2')
    for r in range(rows):
        for c in range(cols):
            if mask[r, c] == 255:
                hsv.itemset((r, c, 0), hsv.item(r, c, 0) -h)
                hsv.itemset((r, c, 1), hsv.item(r, c, 1) +90-s)
                hsv.itemset((r, c, 2), hsv.item(r, c, 2) +90-v)
    img2 = cv2.cvtColor(hsv, cv2.COLOR_HSV2BGR)
    #将图像进行输出,使用show()也是可以显示的。
    img = cv2.resize(img, (500, 500))
    cv2.imshow("img2", img2)
    k = cv2.waitKey(1)&0xFF
    if k == 27: #esc exit
        break

#cv2.waitKey(0)
cv2.destroyAllWindows()

inserte la descripción de la imagen aquí

3. Resumen

Este blog presenta cómo usar Python y OpenCV para la segmentación de color, que utiliza el espacio de color HSV y el algoritmo de segmentación de umbral. Los pasos para lograr la segmentación del color incluyen: leer archivos de imagen, convertir espacios de color, calcular umbrales, segmentar imágenes, eliminar ruido, etc. A través del código del ejemplo, podemos tener una comprensión más profunda del proceso de implementación de la segmentación por color.

Supongo que te gusta

Origin blog.csdn.net/weixin_44598554/article/details/130627957
Recomendado
Clasificación