División del espacio de color RGB: uso de división y matrices de OpenCV
Tabla de contenido
Generar gráficos RGB
En principio, la matriz de imagen de color RGB se almacena en forma de píxeles. El siguiente ejemplo dibujará tres círculos en los tres colores primarios rojo, verde y azul. Se debe prestar especial atención a que el formato de la imagen de visualización de pyplot sea RGB (A), por lo que se requiere la conversión del espacio de color cv2.cvtColor (imagen, cv2.COLOR_RGB2BGRA)
Código de referencia
from matplotlib import pyplot as plt
import cv2
import numpy as np
# 生成一个 640*480 的 BGR 三个通道的彩色图片,底色全为0
canvas = np.zeros((480, 640, 3), dtype='uint8')
image_path='../data/diy.jpg'
# 圆半径为 90 pixel
radius = 90
# 配色为 BGR
blue = (255, 0, 0)
green = (0, 255, 0)
red = (0, 0, 255)
# 圆边厚度为 10 pixel
thickness = 10
# 画出 红绿蓝三个图片
image = cv2.circle(canvas, (320, 200), radius, red, thickness)
image = cv2.circle(canvas, (220, 300), radius, green, thickness)
image = cv2.circle(canvas, (420, 300), radius, blue, thickness)
# 因为 pyplot 显示图片的格式为 RGB(A) 所以要进行颜色空间转换
toGBR = cv2.cvtColor(image,cv2.COLOR_RGB2BGRA)
# the image in the BGR 8-bit format
cv2.imwrite(image_path,canvas)
plt.figure(figsize=(8,12))
plt.subplot(211), plt.title('BGR format')
plt.imshow(image) # image 为 BGR 8-bit 格式,而 plt 以 RGB 方式显示,所以颜色会不对
plt.subplot(212), plt.title('RGB(A) format')
plt.imshow(toGBR) # toGBR 为 RGB(A) 格式,这才是正确的配色
plt.show()
Figura 1. Muestra la diferencia entre los formatos BGR y RGB(A), la coincidencia de color de los gráficos en el lado derecho es correcta
Dividir canales RGB para mostrar en escala de grises
Divida la imagen en color de acuerdo con el canal BGR. El siguiente ejemplo muestra una imagen separada para cada canal de la imagen diy.jpg generada anteriormente. En el orden de visualización, se puede encontrar que los canales son rojo (0), verde ( 1), azul (2).
Código de referencia
from matplotlib import pyplot as plt
import cv2
#IMREAD_COLOR 会将图片以 BGR 8-bit 格式读入
img1 = cv2.imread('../data/diy.jpg',cv2.IMREAD_COLOR)
# 将图片依 BGR 分割成三个通道
channels = cv2.split(img1)
# color in BGR
titles=['Blue', 'Green', 'Red']
figure, plots = plt.subplots(ncols=3, nrows=1,figsize=(12,6))
for i, subplot in zip(range(3), plots):
subplot.imshow(channels[i],'gray')
subplot.set_axis_off()
subplot.set_title(titles[i])
plt.show()
Figura 2. Espacio de color BGR dividido
Canales RGB divididos para mostrar en color
Los pasos del procesamiento son:
- Cargue una imagen en color y léala en formato BGR de 8 bits (opencv)
- Dividir canales de color independientes (opencv)
- Crear una imagen en blanco (np)
- Dar el color de un canal específico a una imagen en blanco
- Convertir al espacio de color de plt (opencv)
- Mostrar resultados usando plt (matplotlib)
Código de referencia
from matplotlib import pyplot as plt
import numpy as np
import cv2
#加载彩色图像
img = cv2.imread('../data/diy.jpg',cv2.IMREAD_COLOR)
# 分割独立的颜色通道
channels = cv2.split(img)
# color in BGR
titles=['Blue', 'Green', 'Red']
figure, plots = plt.subplots(ncols=3, nrows=1,figsize=(12,6))
for i, subplot in zip(range(3), plots):
# 创建空白图片
temp = np.zeros(img.shape, dtype='uint8')
# 将特定通道的颜色给予空白图片
temp[:,:,i] = channels[i] # img[:,:,i]
# 转换成 plt 的颜色空间
toGBR = cv2.cvtColor(temp,cv2.COLOR_RGB2BGRA)
subplot.imshow(toGBR)
subplot.set_title(titles[i])
subplot.set_axis_off()
plt.show()
Figura 3. Canales RGB respectivos mostrados en color
Si se trata de una imagen con un fondo blanco, dicho método de visualización generalmente no puede lograr el efecto deseado, como se muestra en el código a continuación, porque el fondo blanco hará que toda la visualización de un solo canal muestre el color de fondo de un solo canal. , que no es fácil de resaltar el objetivo. Además, el rojo, el azul y el verde en los ojos humanos a menudo son el resultado de una mezcla, por lo que si desea descubrir los colores rojo, azul y verde por separado, generalmente usa el espacio de color HSV.
from matplotlib import pyplot as plt
import numpy as np
import cv2
#加载彩色图像
img = cv2.imread('../data/b.png',cv2.IMREAD_COLOR)
channels = cv2.split(img)
# color in BGR
titles=['Blue', 'Green', 'Red']
figure, plots = plt.subplots(ncols=4, nrows=1,figsize=(12,4))
for i, subplot in zip(range(4), plots):
if i < 3:
temp = np.zeros(img.shape, dtype='uint8')
temp[:,:,i] = channels[i] # img[:,:,i]
toGBR = cv2.cvtColor(temp,cv2.COLOR_RGB2BGRA)
subplot.imshow(toGBR)
subplot.set_title(titles[i])
subplot.set_axis_off()
else:
toGBR = cv2.cvtColor(img,cv2.COLOR_RGB2BGRA)
subplot.imshow(toGBR)
subplot.set_title('Origin')
subplot.set_axis_off()
plt.show()
Figura 4. Canales RGB respectivos mostrados en color
Referencias
- API de OpenCV, https://docs.opencv.org/
- Introducción a las imágenes, https://docs.opencv.org/4.x/db/deb/tutorial_display_image.html
- matplotlib.pyplot.subplot, https://matplotlib.org/stable/api/_as_gen/matplotlib.pyplot.subplot.html#matplotlib.pyplot.subplot
- matplotlib.pyplot.imshow, https://matplotlib.org/stable/api/_as_gen/matplotlib.pyplot.imshow.html