import matplotlib.pyplot as plt
import numpy as np
import cv2
# To fixz a google colab issue on cv2.imshow() replaced by cv2_imshow()
from google.colab.patches import cv2_imshow
import requests
%pylab inline
# url_image = r'https://i0.wp.com/owdin.live/wp-content/uploads/2019/12/1_gUoANPVUnpV-5hNg2HRX5Q.png'
url_image = r'https://journals.openedition.org/itti/docannexe/image/1146/img-1.png'
resp = requests.get(url_image, stream=True).raw
image_array = np.asarray(bytearray(resp.read()), dtype="uint8")
print(image_array)
image_rgb = cv2.imdecode(image_array, cv2.IMREAD_COLOR)
file_name = '/content/Toureiffel_I.jpg'
image_rgb = cv2.cvtColor(cv2.imread(file_name), cv2.COLOR_BGR2RGB)
image_grayscale = cv2.cvtColor(image_rgb, cv2.COLOR_RGB2GRAY)
image_reverse = cv2.bitwise_not(image_rgb)
pixel_threshold = 127
(thresh, image_bw) = cv2.threshold(image_grayscale, pixel_threshold, 255, cv2.THRESH_BINARY)
Hori = np.concatenate((image_rgb, image_reverse), axis=1)
plt.imshow(Hori)
plt.title("3D")
plt.show()
Hori = np.concatenate((image_grayscale, image_bw), axis=1)
plt.imshow(Hori)
plt.title("1D")
plt.show()
Charger une image et l'afficher en couleur RGB ou BGR ...
Depuis l'image en nuance de gris, on applique un filtre binaire afin de passer en Noir et Blanc (B&W).
image_size = 64
image_resized_color = cv2.resize(image_rgb , dsize=(image_size, image_size), interpolation=cv2.INTER_CUBIC)
res = cv2.cvtColor(image_resized_color,cv2.COLOR_RGB2GRAY) #TO 3D to 1D
print(image_resized_color.shape)
image_resized_color = cv2.threshold(res, 127, 255, cv2.THRESH_BINARY)[1]
for row in range(0, image_size):
for col in range(0, image_size):
if image_resized_color[row][col] == 255:
print('°',end=' ')
else:
print(' ',end=' ')
print('')
cv2_imshow(image_resized_color)
(64, 64, 3)
pixel_threshold = 127
(thresh, image_bw) = cv2.threshold(image_grayscale, pixel_threshold, 255, cv2.THRESH_BINARY)
cv2_imshow(image_bw)
pixel_poderation = 10
#defining a vertical edge detection kernel
kernel = np.matrix([[-pixel_poderation,0,pixel_poderation],[-2*pixel_poderation,0,2*pixel_poderation],[-pixel_poderation,0,pixel_poderation]])
print(kernel)
img_1 = cv2.filter2D(image_bw, -1, kernel)
[[-10 0 10]
[-20 0 20]
[-10 0 10]]
#defining an horizontal edge detection kernel
kernel = np.matrix([[-pixel_poderation,-2*pixel_poderation,-pixel_poderation],[0,0,0],[pixel_poderation,2*pixel_poderation,pixel_poderation]])
print(kernel)
img_2 = cv2.filter2D(image_bw, -1, kernel)
[[-10 -20 -10]
[ 0 0 0]
[ 10 20 10]]
kernel = np.matrix([[-2*pixel_poderation,-2*pixel_poderation,0],[-2*pixel_poderation,0,2*pixel_poderation],[0,2*pixel_poderation,2*pixel_poderation]])
print(kernel)
img_3 = cv2.filter2D(image_bw, -1, kernel)
[[-20 -20 0]
[-20 0 20]
[ 0 20 20]]
Hori = np.concatenate((img_1, img_2, img_3), axis=1)
cv2_imshow(Hori)
import matplotlib.pyplot as plt
# Générer et afficher l'histogramme
# Pour le normaliser : argument density=True dans plt.hist
# Pour avoir l'histogramme cumulé : argument cumulative=True
n, bins, patches = plt.hist(image_grayscale.flatten(), bins=range(256))
plt.show()
image_result = image_rgb.copy()
image_temp = cv2.cornerHarris(image_grayscale,2,3,0.04)
image_temp = cv2.dilate(image_temp,None)
image_result[image_temp>0.01*image_temp.max()]=[0,255,0] #BGR
Hori = np.concatenate((image_rgb, image_result), axis=1)
plt.figure(figsize=(20,20))
plt.imshow(Hori)
plt.title("Harris Corner Detection")
plt.show()
image_result = image_rgb.copy()
corners = cv2.goodFeaturesToTrack(image_grayscale,20,0.01,10)
corners = np.int0(corners)
for i in corners:
x,y = i.ravel()
cv2.circle(image_result,(x,y),3,(0, 255, 0),-1)
Hori = np.concatenate((image_rgb, image_result), axis=1)
plt.figure(figsize=(20,20))
plt.imshow(Hori)
plt.title("Shi-Tomasi Corner Detector")
plt.show()
SIFT et SURF sont soumis à licences logiciels qui ne semblent pas toujours disponibles.
Par exemple la version 4.1.2 de cv2 n'offre pas ces fonctionnalités.
Alors que la version 4.5.5 semble fonctionner correctement avec SIFT.
SIFT est utilisé pour détecter les coins, les glob, les cercles, etc... Il est également utilisé pour redimensionner une image.
Considérez ces trois images différentes d'un même objet. Bien qu'elles diffèrent par la couleur, la rotation et l'angle, vous savez que ce sont les trois images représantants le même objet. Comment un ordinateur peut-il être capable de l'identifier ?
Les algorithmes de détection de coin Harris et de détection de coin Shi-Tomasi échouent dans ce cas. Mais l'algorithme SIFT joue ici un rôle essentiel. Il peut détecter les caractéristiques de l'image indépendamment de sa taille et de son orientation.
import sys
if 'google.colab' in sys.modules:
import subprocess
subprocess.call("pip install -U opencv-python".split())
# subprocess.call("wget https://journals.openedition.org/itti/docannexe/image/1146/img-1.png".split())
else:
print('/!\\ Issue...')
from random import randrange
import matplotlib.pyplot as plt
import numpy as np
import cv2
print("CV2 relese = " + cv2.__version__)
image_result = image_rgb.copy()
feature_extractor = cv2.SIFT_create()
kp, des = feature_extractor.detectAndCompute(image_grayscale,None)
image_result=cv2.drawKeypoints(image_grayscale,kp,None,flags=cv2.DRAW_MATCHES_FLAGS_DRAW_RICH_KEYPOINTS)
Hori = np.concatenate((image_rgb, image_result), axis=1)
plt.figure(figsize=(20,20))
plt.imshow(Hori)
plt.title("Scale-Invariant Feature Transform")
plt.show()
L'algorithme SURF est simplement une version améliorée de SIFT.
Nous verrons comment extraire une autre fonctionnalité appelée Blob.
BLOB signifie Binary Large Object. Il fait référence à un groupe de pixels ou de régions connectés dans une image binaire particulière qui partage une propriété commune. Ces régions sont des contours dans OpenCV avec quelques fonctionnalités supplémentaires telles que le centroïde, la couleur, la zone, une moyenne et un écart type des valeurs de pixel dans la région couverte. Allons mettre en œuvre celui-ci.
print("CV2 relese = " + cv2.__version__)
img = image_rgb.copy()
# cv2.xfeatures2d.SURF_create()
feature_extractor = cv2.SURF_create(400)
kp, des = feature_extractor.detectAndCompute(img,None)
image_result = cv2.drawKeypoints(img,kp,None,(255,0,0),4)
Hori = np.concatenate((image_rgb, image_result), axis=1)
plt.figure(figsize=(20,20))
plt.imshow(Hori)
plt.title("Speeded-up Robust Features")
plt.show()
detector = cv2.SimpleBlobDetector_create()
keypoints = detector.detect(image_grayscale)
im_with_keypoints = cv2.drawKeypoints(image_grayscale, keypoints, np.array([]), (0,255,0), cv2.DRAW_MATCHES_FLAGS_DRAW_RICH_KEYPOINTS)
Hori = np.concatenate((image_rgb, im_with_keypoints), axis=1)
plt.figure(figsize=(20,20))
plt.imshow(Hori)
plt.title("Detection des Blob")
plt.show()
Les caractéristiques sont généralement des points distincts dans une image et le descripteur donne une signature, il décrit donc le point clé qui est considéré. Il extrait le voisinage local autour de ce point afin qu'un patch d'image local soit créé et qu'une signature de ce patch local soit calculée.
Avant l'avènement de l'apprentissage en profondeur, HoG était l'un des descripteurs de caractéristiques les plus importants pour les applications de détection d'objets. HoG est une technique utilisée pour compter l'apparition d'une orientation de gradient dans des parties localisées d'une image.
from skimage.feature import hog
img = image_rgb.copy()
_, image_hog = hog(img, orientations=8, pixels_per_cell=(16, 16),
cells_per_block=(1, 1), visualize=True, multichannel=True)
# Hori = np.concatenate((image_rgb, image_hog), axis=1)
plt.figure(figsize=(10,20))
plt.imshow(image_rgb)
plt.title("Origin")
plt.show()
plt.figure(figsize=(10,20))
plt.imshow(image_hog)
plt.title("HoG")
plt.show()
BRIEF est une alternative au descripteur SIFT populaire et ils sont plus rapides à calculer et plus compacts.
img = image_rgb.copy()
star = cv2.xfeatures2d.StarDetector_create()
brief = cv2.xfeatures2d.BriefDescriptorExtractor_create()
kp = star.detect(img,None)
kp, des = brief.compute(img, kp)
print( brief.descriptorSize() )
print( des.shape )
image_brief = cv2.drawKeypoints(img, kp, None, color=(0, 255, 0), flags=0)
Hori = np.concatenate((image_rgb, image_brief), axis=1)
plt.figure(figsize=(20,20))
plt.imshow(Hori)
plt.title("Binary Robust Independent Elementary Features")
plt.show()
ORB est un algorithme de reconnaissance faciale à un coup. Il est actuellement utilisé dans vos téléphones portables et dans des applications comme Google Photos dans lesquelles vous regroupez les personnes que vous voyez 'tagger', les images sont regroupées en fonction des personnes. Cet algorithme ne nécessite aucun type de calculs majeurs. Il ne nécessite pas de GPU. Ici, deux algorithmes sont impliqués. RAPIDE et BREF. Cela fonctionne sur la correspondance des points clés. Correspondance de points clés de régions distinctives dans une image comme les variations d'intensité.
img = image_rgb.copy()
orb_score = cv2.ORB_create(nfeatures=200)
kp = orb_score.detect(image_grayscale, None)
kp, des = orb_score.compute(img, kp)
image_orb = cv2.drawKeypoints(img, kp, None, color=(0, 255, 0), flags=0)
Hori = np.concatenate((image_rgb, image_orb), axis=1)
plt.figure(figsize=(20,20))
plt.imshow(Hori)
plt.title("Oriented FAST and Rotated BRIEF")
plt.show()
La correspondance des caractéristiques revient à comparer les caractéristiques de deux images qui peuvent être différentes en termes d'orientation, de perspective, d'éclairage ou même de tailles et de couleurs différentes. Voyons sa mise en œuvre.
file_name2 = '/content/Toureiffel_II.jpg'
image2_rgb = cv2.cvtColor(cv2.imread(file_name2), cv2.COLOR_BGR2RGB)
image2_grayscale = cv2.cvtColor(image2_rgb, cv2.COLOR_RGB2GRAY)
print('Original Dimensions Source: ',image_grayscale.shape)
print('Original Dimensions Target: ',image2_grayscale.shape)
orb_score = cv2.ORB_create(nfeatures=500)
kp1, des1 = orb_score.detectAndCompute(image_grayscale, None)
kp2, des2 = orb_score.detectAndCompute(image2_grayscale, None)
bf = cv2.BFMatcher(cv2.NORM_HAMMING, crossCheck=True)
matches = bf.match(des1, des2)
matches = sorted(matches, key=lambda x: x.distance)
match_img = cv2.drawMatches(image_grayscale, kp1, image2_grayscale, kp2, matches[:50], None)
Hori = np.concatenate((image_grayscale, image2_grayscale), axis=1)
plt.figure(figsize=(20,20))
plt.imshow(Hori)
plt.title("Source & target")
plt.show()
plt.figure(figsize=(20,20))
plt.imshow(match_img)
plt.title("Match")
plt.show()