Répertoire d'articles
OpenCV-Python: opérations de base
9 Opérations de base des images
Objectifs
• Obtenir des valeurs de pixels et les modifier
• Obtenir des attributs d'image (informations)
• ROI de l'image ()
• Diviser et fusionner le canal d'image
Presque toutes ces opérations ont une relation plus étroite avec Numpy qu'avec OpenCV, vous pouvez donc vous familiariser avec l'aide de Numpy nous écrivons un code plus performant.
(Les exemples seront affichés dans le terminal Python, car la plupart d'entre eux n'ont qu'une seule ligne de code)
9.1 Obtenir et modifier la valeur du pixel
Nous devons d'abord lire dans une image:
import cv2
import numpy as np
img=cv2.imread('messi5.jpg')
Vous pouvez obtenir la valeur du pixel en fonction des coordonnées de ligne et de colonne du pixel. Pour les images BGR, la valeur de retour est la valeur de B, G, R. Pour les images en niveaux de gris, il retournera sa valeur de niveaux de gris (luminosité? Intensité)
import cv2
import numpy as np
img=cv2.imread('messi5.jpg')
px=img[100,100]
print(px)
blue=img[100,100,0]
print(blue)
Vous pouvez modifier la valeur du pixel de la même manière.
import cv2
import numpy as np
img=cv2.imread('messi5.jpg')
img[100,100]=[255,255,255]
print(img[100,100])
# [255 255 255]
Attention: Numpy est un progiciel optimisé pour les opérations matricielles rapides. Par conséquent, nous vous déconseillons d'obtenir les valeurs des pixels une par une et de les modifier une par une. Ce sera très lent. N'utilisez pas de boucles si vous pouvez effectuer des opérations matricielles.
Remarque: La méthode mentionnée ci-dessus est utilisée pour sélectionner une région de la matrice, par exemple, les 5 premières lignes et les 3 dernières colonnes. Pour obtenir la valeur de chaque pixel, il serait peut-être préférable d'utiliser les tableaux array.item () et array.itemset () de Numpy. Mais la valeur de retour est un scalaire. Si vous voulez obtenir toutes les
valeurs de B, G, R , vous devez utiliser array.item () pour les diviser.
Une meilleure façon d'obtenir des valeurs de pixels et de les modifier.
import cv2
import numpy as np
img=cv2.imread('messi5.jpg')
print(img.item(10,10,2))
img.itemset((10,10,2),100)
print(img.item(10,10,2))
# 59
# 100
9.2 Obtenir les attributs d'image
Les attributs de l'image incluent: ligne, colonne, canal, type de données d'image, nombre de pixels, etc. img.shape peut obtenir la forme de l'image. Sa valeur de retour est un tuple contenant le nombre de lignes, de colonnes et de canaux.
import cv2
import numpy as np
img=cv2.imread('messi5.jpg')
print(img.shape)
#(342, 548, 3)
Remarque: si l'image est une image en niveaux de gris, la valeur renvoyée est uniquement le nombre de lignes et de colonnes. Ainsi, en vérifiant cette valeur de retour, vous pouvez savoir si l'image chargée est une image en niveaux de gris ou une image en couleur.
img.size peut renvoyer le nombre de pixels de l'image:
import cv2
import numpy as np
img=cv2.imread('messi5.jpg')
print(img.size, img.dtype) # 返回的是图像的数据类型.
# 562248 uint8
# uint8*
Remarque: img.dtype est très important lors du débogage. Parce qu'il y a souvent des incohérences dans les types de données dans le code OpenCV Python.
9.3 ROI de l'image
Parfois, vous devez opérer sur une zone spécifique d'une image. Par exemple, si nous voulons détecter la position des yeux dans une image, nous devons d'abord trouver le visage dans l'image, puis trouver les yeux dans la zone du visage, au lieu de chercher directement dans une image. Cela améliorera la précision et les performances du programme.
Le retour sur investissement est également obtenu à l'aide de l'indexation Numpy. Maintenant, nous sélectionnons la partie de la balle et la copions dans d'autres zones de l'image.
import cv2
import numpy as np
img=cv2.imread('messi5.jpg')
ball=img[280:340,330:390]
img[273:333,100:160]=ball
img=cv2.imshow('test', img)
cv2.waitKey(0)
Jetez un œil aux résultats:
9.4 Diviser et fusionner les canaux d'image
Parfois, nous devons faire fonctionner les trois canaux BGR séparément. C'est ce dont vous avez besoin pour diviser le BGR en un seul canal. Parfois, vous devez fusionner les images de canaux indépendants en une seule image BGR. Tu peux le faire:
import cv2
import numpy as np
img=cv2.imread('/home/duan/workspace/opencv/images/roi.jpg')
b,g,r=cv2.split(img)
img=cv2.merge(b,g,r)
ou:
import cv2
import numpy as np
img=cv2.imread('/home/duan/workspace/opencv/images/roi.jpg')
b=img[:,:,0]
Si vous souhaitez rendre la valeur du canal rouge de tous les pixels 0, vous n'avez pas besoin de fractionner puis d'attribuer des valeurs. Vous pouvez utiliser l'indexation Numpy directement, ce qui sera plus rapide.
import cv2
import numpy as np
img=cv2.imread('/home/duan/workspace/opencv/images/roi.jpg')
img[:,:,2]=0
Attention: cv2.split () est une opération qui prend du temps. Utilisez-le uniquement lorsque vous en avez vraiment besoin et essayez de l'utiliser si vous pouvez utiliser l'indexation Numpy.
9.5 Agrandissement (remplissage) de l'image
Si vous souhaitez créer une bordure autour de l'image, tout comme un cadre photo, vous pouvez utiliser la fonction cv2.copyMakeBorder (). Ceci est souvent utilisé dans les opérations de convolution ou de remplissage nul. Cette fonction comprend les paramètres suivants:
• image d'entrée src
• haut, bas, gauche, droite le nombre de pixels correspondant à la bordure.
• borderType pour ajouter ce type de bordure, le type est le suivant:
-cv2.BORDER_CONSTANT pour ajouter une bordure de valeur constante avec une couleur et le paramètre suivant (valeur) est requis.
- Cv2.BORDER_REFLECT L'image miroir de l'élément frontière. Par exemple: fedcba | abcde-fgh | hgfedcb
- cv2.BORDER_REFLECT_101 ou cv2.BORDER_DEFAULT est le même que ci-dessus, mais légèrement modifié. Par exemple: gfedcb | abcdefgh | gfedcba
- cv2.BORDER_REPLICATE répète le dernier élément. Par exemple: aaaaaa | abcdefgh | hhhhhhh
- cv2.BORDER_WRAP Je ne sais pas quoi dire, comme ceci: cdefgh | abcdefgh | abcdefg
• value border color, si le type de bordure est cv2.BORDER_CONSTANT
Afin de mieux comprendre ces types, veuillez consulter le programme de démonstration ci-dessous.
import cv2
import numpy as np
from matplotlib import pyplot as plt
BLUE=[255,0,0]
img1=cv2.imread('opencv_logo.png')
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()
Les résultats sont les suivants (puisque matplotlib est utilisé pour le dessin, les positions de R et B sont échangées. Dans OpenCV, il est arrangé par BGR, et dans matplotlib, il est arrangé par RVB):
Pour plus d'informations, veuillez faire attention au compte officiel: