[Reproducido] El funcionamiento básico de las imágenes OpenCV + Python (10)

En el último tutorial, presentamos la función de usar el lápiz del mouse. En este tutorial, hablaremos sobre las operaciones básicas del procesamiento de imágenes OpenCV.

Lo que necesitamos introducir en este tutorial es:

· Ver los valores de píxeles de la imagen y modificarlos
· Ver las propiedades de la imagen
· Ver la región de interés (ROI)
· Dividir y fusionar la imagen

Todas las operaciones de este tutorial están básicamente relacionadas con Numpy, no con OpenCV. Para usar OpenCV para escribir código mejor optimizado, se requiere una gran cantidad de conocimientos de Numpy.

Ver y modificar valores de píxeles

Si queremos ver el valor de píxel de un determinado píxel en una imagen, primero debemos localizar y calibrar sus coordenadas. Primero veamos una imagen en color (sigue siendo nuestro gato, este tutorial es nuestro protagonista):
Inserte la descripción de la imagen aquí
Ahora quiero ver el valor de píxel de una determinada coordenada, ingresamos el código en pycharm:

	view plaincopy to clipboardprint?
import cv2  
import numpy as np  

img = cv2.imread("cat.jpg")  
#获取像素值  
px = img[200,200]  
print(px)  

El código es para ver el valor de píxel en las coordenadas de la imagen (200, 200), veamos el resultado:
Inserte la descripción de la imagen aquí

En el tutorial anterior hablamos de que OpenCV lee imágenes no de canales RGB, sino de canales BGR, luego la salida del programa [178, 189, 186] corresponde a los píxeles BGR, podemos verificar:

	view plaincopy to clipboardprint?
import cv2  
import numpy as np  

img = cv2.imread("cat.jpg") 
 
#获取像素值  
px = img[200,200]  
B = img[200,200,0]  
G = img[200,200,1]  
R = img[200,200,2]  
print(px,B,G,R)  

Inserte la descripción de la imagen aquí
Ahora asumimos que si la imagen no está en color, sino en una imagen en escala de grises en blanco y negro, ¿cómo se generará? Experimente primero:
Inserte la descripción de la imagen aquí
todavía usamos el código justo ahora para experimentar (siempre que la imagen haya sido en escala de grises, que se discutirá más adelante), el efecto:
Inserte la descripción de la imagen aquí
puede ver que los píxeles de BGR son los mismos, llegamos a una conclusión: para escala de grises En una imagen, el valor del píxel de salida es esencialmente su valor de intensidad de brillo, el rango de valores está entre 0-255, cuando es 0, es todo negro, de lo contrario es blanco.

A continuación, modifiquemos el valor del píxel, asignemos el valor del píxel de la coordenada especificada con una matriz:

	view plaincopy to clipboardprint?
import cv2  
import numpy as np  
  
img = cv2.imread("cat1.jpg")  
#获取像素值  
px = img[200,200]  
print(px)  
img[200,200] = [225,225,225]  
print(img[200,200])  

Ver la salida:
Inserte la descripción de la imagen aquí

Como puede ver, el valor de píxel inicial va seguido del valor de píxel modificado.

En términos generales, una matriz suele seleccionar un área determinada, como las primeras filas o las últimas columnas. Para acceder a un determinado píxel, los métodos de matriz Numpy, array.item () y array.itemset () tienen un mejor efecto. Pero devuelve un escalar. Entonces, si queremos acceder a todos los valores B, G, R, necesitamos llamar a array.item () por separado, veamos el código (aún tomando las coordenadas 200, 200 como ejemplo):

	view plaincopy to clipboardprint?
import cv2  
import numpy as np  
  
img = cv2.imread("cat.jpg")  
#获取像素值  
px = img[200,200]  
print(px)  
print(img.item(200,200,0))  

Usamos item para generar el valor B del píxel, que es el valor del píxel azul:
Inserte la descripción de la imagen aquí

El experimento muestra que el efecto es el mismo que antes.

Para la asignación de las coordenadas especificadas, podemos usar la función de conjunto de elementos para tener una precisión de un determinado píxel. Por ejemplo, ahora solo cambio el valor del píxel azul:

	view plaincopy to clipboardprint?
import cv2  
import numpy as np  
  
img = cv2.imread("cat.jpg")  
#获取像素值  
px = img[200,200]  
print(px)  
print(img.item(200,200,0))  
img.itemset((200,200,0),100)  
print(img.item(200,200,0))  

Inserte la descripción de la imagen aquí

Se puede ver que la asignación del canal de color especificado es completamente posible.

Ver propiedades de la imagen

Ahora estudiaremos los distintos atributos de la imagen. Los atributos de la imagen incluyen el número de filas, columnas y canales, el tipo de datos de la imagen, el número de píxeles, etc.

Para una imagen, usamos forma para devolver el número de filas, columnas y el número de canales de color:

	view plaincopy to clipboardprint?
import cv2  
import numpy as np  
  
img = cv2.imread("cat.jpg")  
print(img.shape)  

Inserte la descripción de la imagen aquí
El tercer valor de la salida representa el número de elemento de los tres canales del BGR de la imagen, que es 3. Ahora experimentamos con imágenes en escala de grises:

	view plaincopy to clipboardprint?
import cv2  
import numpy as np  
  
img = cv2.imread("cat.jpg")  
img = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)  
print(img.shape)  

La imagen en escala de grises se explicará en un tutorial posterior, aquí se usa como un experimento:
Inserte la descripción de la imagen aquí
puede ver que si la imagen es en escala de grises, la tupla devuelta solo contiene el número de filas y columnas, por lo que esto es para verificar si la imagen cargada es La escala de grises también es un buen método para colorear.

El número total de píxeles de la imagen actual se puede devolver por tamaño:

	view plaincopy to clipboardprint?
import cv2  
import numpy as np  
  
img = cv2.imread("cat.jpg")  
print(img.size)  

Inserte la descripción de la imagen aquí
El tipo de datos de la imagen se puede obtener mediante dtype:

	view plaincopy to clipboardprint?
import cv2  
import numpy as np  
  
img = cv2.imread("cat.jpg")  
print(img.dtype)  

image.png

El formato predeterminado de la función imread para leer la imagen es uint8, por lo que todas las devoluciones están en este formato. En el futuro, cuando aprendamos el marco de aprendizaje profundo, encontraremos que cuando se usa el formato de datos de imagen de uint8 para el entrenamiento de modelos, la normalización de datos (etapa de preprocesamiento) dará como resultado una pérdida de precisión y, finalmente, una disminución en la precisión de segmentación. Por supuesto, esto es algo posterior, no lo mencionaremos ahora.

Si queremos modificar el formato de la imagen, necesitamos usar la función astype, y ahora modificar la imagen al formato float32 (las imágenes en este formato se usan ampliamente en el entrenamiento de modelos de aprendizaje profundo):

	view plaincopy to clipboardprint?
import cv2  
import numpy as np  
  
img = cv2.imread("cat.jpg").astype(np.float32)  
print(img.dtype)  

Inserte la descripción de la imagen aquí

dtype es muy importante al depurar, porque una gran cantidad de errores en el código OpenCV-Python son causados ​​por tipos de datos no válidos, y a menudo encontraremos estos problemas en el aprendizaje futuro.

ROI de la imagen

La selección de un área específica en la imagen se llama ROI, que en realidad es una operación en las coordenadas xy de la imagen. Veamos un ejemplo:

	view plaincopy to clipboardprint?
import cv2  
import numpy as np  
  
img = cv2.imread("cat.jpg")  
husky = img[1:240,60:270]  
cv2.imshow("img",husky)  
cv2.waitKey(0)  
cv2.destroyAllWindows()  

Inserte la descripción de la imagen aquí

La esencia es equivalente a interceptar una cierta parte de la imagen. Ahora hagamos algunas operaciones interesantes para cubrir la parte interceptada a otras partes de la imagen. La esencia es equivalente a la modificación de píxeles mencionada anteriormente:

view plaincopy to clipboardprint?
import cv2  
import numpy as np  
  
img = cv2.imread("cat.jpg")  
husky = img[1:240,60:270]  
img[61:300,270:480] = husky  
cv2.imshow("img",img)  
cv2.waitKey(0)  
cv2.destroyAllWindows()  

image.png

Dividir y fusionar canales de imágenes

A veces necesitamos operar por separado en las imágenes de los canales B, G y R. En este caso, la imagen BGR debe dividirse en canales individuales. Necesita usar la función de división y la función de combinación, sus funciones son separación y combinación respectivamente:

b, g, r = cv2.split (img) #Canal de imagen dividido

img = cv2.merge ((b, g, r))

Esta operación puede separar los tres canales BGR, de modo que se pueda operar un determinado canal. Por ejemplo, ahora configuramos todos los píxeles R en 0:

	view plaincopy to clipboardprint?
import cv2  
import numpy as np  
  
img = cv2.imread("cat.jpg")  
b,g,r = cv2.split(img) #拆分图像通道  
img[:,:,2] = 0  
r = img[:,:,2]  
img = cv2.merge((b,g,r))  
cv2.imshow("img",img)  
cv2.waitKey(0)  
cv2.destroyAllWindows()  

r es el canal R, vea el efecto:

image.png
Después de quitar el canal rojo, nuestro gato se puso un poco verde. Por supuesto, también puede experimentar con otros canales.

Relleno del borde de la imagen

Si desea crear un borde alrededor de la imagen (como un marco de fotos), puede usar la función cv2.copyMakeBorder (). Tiene más aplicaciones en operaciones de convolución (muy importante), relleno de ceros, etc. Esta función toma los siguientes parámetros:

cv2.copyMakeBorder (src, top, bottom, left, right, borderType [, dst [, value]])

· Imagen de entrada src

· Arriba, abajo, izquierda, derecha: el ancho del borde en píxeles en la dirección correspondiente

· Valor: cv2.BORDER_CONSTANT, cv2.BORDER_REFLECT, cv2.BORDER_REFLECT_101 o cv2.BORDER_DEFAULT, cv2.BORDER_REPLICATE, cv2.BORDER_WRAP
· Imagen.png
cv2.BORDER_defLECT_101 o cv2.BORDER_defLECT_101 o cv2.BORDER con cambios leves como se muestra arriba, pero con los mismos cambios que se muestran arriba en | gfedcba

cv.BORDER_REPLICATE: el último píxel se copia durante todo el proceso, como: aaaaaa | abcdefgh | hhhhhhh

El intercambio de píxeles de dirección simétrica cv.BORDER_WRAP es como: cdefgh | abcdefgh | abcdefg así.

Veamos el código:

	view plaincopy to clipboardprint?
import cv2  
from matplotlib import pyplot as plt  
  
BLUE = [255,0,0]  
  
img1 = cv2.imread('cat.jpg')  
  
replicate = cv2.copyMakeBorder(img1,10,10,10,10,cv2.BORDER_REPLICATE)  
reflect = cv2.copyMakeBorder(img1,10,10,10,10,cv2.BORDER_REFLECT)  
reflect101 = cv2.copyMakeBorder(img1,10,10,10,10,cv2.BORDER_REFLECT_101)  
wrap = cv2.copyMakeBorder(img1,10,10,10,10,cv2.BORDER_WRAP)  
constant= cv2.copyMakeBorder(img1,10,10,10,10,cv2.BORDER_CONSTANT,value=BLUE)  
  
plt.subplot(231),plt.imshow(img1,'gray'),plt.title('ORIGINAL')  
plt.subplot(232),plt.imshow(replicate,'gray'),plt.title('REPLICATE')  
plt.subplot(233),plt.imshow(reflect,'gray'),plt.title('REFLECT')  
plt.subplot(234),plt.imshow(reflect101,'gray'),plt.title('REFLECT_101')  
plt.subplot(235),plt.imshow(wrap,'gray'),plt.title('WRAP')  
plt.subplot(236),plt.imshow(constant,'gray'),plt.title('CONSTANT')  
  
plt.show()  

Efecto experimental:
Inserte la descripción de la imagen aquí

Los experimentos en los cinco parámetros pueden ver diferencias obvias. Por supuesto, para facilitar la comparación y visualización de imágenes, usamos la biblioteca matplotlib, pero esto pertenece al conocimiento de Python, por lo que no los presentaré aquí. También puede modificar el código y usar OpenCV para generar otros parámetros.

Vea la página de resumen del artículo https://blog.csdn.net/weixin_44237705/article/details/107864965

Se puede intercambiar más información técnica de openvino en el grupo ~
Inserte la descripción de la imagen aquí

Supongo que te gusta

Origin blog.csdn.net/weixin_44237705/article/details/108049363
Recomendado
Clasificación