Table des matières
Projet Vision Active BUT3
Photo du dispositif
Simulation du dispositif
Vue de la caméra en simulation du dispositif
Vue de la caméra en simulation du dispositif avec segmentation laser
Image captée par la caméra réelle avec mire et longue durée d'exposition
Image RECTIFIÉE captée par la caméra réelle avec mire et longue durée d'exposition
Image captée par la caméra réelle avec longue durée d'exposition
Image captée par la caméra réelle avec courte durée d'exposition et laser sur l'objet
lien vers le TP de géométrie pour la vision
Lien pour récupérer des séquences d'images à traiter
Stocker et dezipper sur D:\etudiants\ : https://bvdp.inetdoc.net/files/iut/3Dscanner/
chaque séquence a un identifiant unique et restera sur le serveur
dans votre code, utiliser des variables String:
fileLocation="D:\\etudiants\\" sequence="imgs2024-03-03_18_32_31.576393R" fileName=fileLocation+sequence+"\\"+"im_00000R.png"
Séquence sans objet sur le plan z=0: https://bvdp.inetdoc.net/files/iut/3Dscanner/imgs2024-03-04_13_39_08.694176R.zip
Code pour récupérer les paramètres de caméra
- getCamera.py
import numpy as np import cv2 from matplotlib import pyplot as plt import math #variables à régler pour pointer vers le bon dossier fileLocation="D:\\etudiants\\" sequence="imgs2024-03-03_18_32_31.576393R" fileName=fileLocation+sequence+"\\"+"CalibResult.npz" #paramètre de la mire dimSquare=0.012 #dimension des carrés sur la mire en mètres-> les unités de longueur sont donc en mètres with np.load(fileName) as X: mtx, dist, rvecs, tvecs = [X[i] for i in ('mtx','dist','rvecs','tvecs')] #nbimages=len(rvecs) #for i in range(nbimages): #si les différentes images d'étalonnage devaient être traitées i=0 #pour récupérer les paramètres de l'image dans laquelle la mire est posée sur le plan horizontal matroti, jacobian=cv2.Rodrigues(rvecs[i]) #Rodrigues permet de calculer la matrice de rotation correspondante axis = np.float32([[0,0,0], [3*dimSquare,0,0], [0,3*dimSquare,0], [0,0,3*dimSquare]]).reshape(-1,3) imgpts, jac = cv2.projectPoints(axis, rvecs[i], tvecs[i], mtx,None) #pour ne pas utiliser les distorsions #matrice de changement de repère contenant les paramètres extrinsèques cRTw=np.concatenate((matroti,tvecs[i]),axis=1) cRTw = np.vstack((cRTw,[0,0,0,1])) print("cRTw: "+str(cRTw)) #paramètres intrinsèques de la caméra alphau=mtx[0][0] alphav=mtx[1][1] pu=mtx[0][2] pv=mtx[1][2]
Calcul de la position du centre optique
La position du centre optique de la caméra dans le repère de travail est obtenue à partir de la matrice caméra:
En observant que le point n'a pas d'image dans
:
Calcul du rayon de projection
L'ensemble des points de la demi-droite (dans le repère de travail
) associés à un point
dans le plan image est donné par:
,
étant un paramètre associé à la distance du point 3D au point
.
Soit le point à l'infini dans la direction de
:
,
et donc
On obtient: qui donne finalement:
En fonction du facteur multiplicatif associé à la représentation homogène de ,
ou
.
Projet et rapport à rendre par mail le 16/02/2025
Le projet rendu en .zip ne doit pas contenir les images fournies par l'enseignant mais doit permettre de les utiliser en réglant les variables indiquant leurs emplacements.
PCA pour ajustement d'un plan sur nuage de points 3D
- pca.py
#analyse en composantes principales (PCA) pour ajuster un plan sur un nuage de points 3D #exemple tiré de: #https://www.bing.com/search?qs=UT&pq=numpy+pca+&sk=CSYN1&sc=6-10&q=numpy+pca+example&cvid=f8480d538ba0461fa6590f521609d926&gs_lcrp=EgRlZGdlKgYIARAAGEAyBggAEEUYOTIGCAEQABhAMgYIAhAAGEAyBggDEAAYQDIGCAQQABhAMgYIBRAAGEDSAQgzMTkxajBqNKgCCLACAQ&FORM=ANAB01&DAF0=1&PC=U531 import numpy as np # Sample data: 5 samples with 3 features data = np.array([[2.5, 2.4, 15], [0.5, 0.7, 0.8], [2.2, 2.9, 1.9], [1.9, 2.2, 1.7], [3.1, 3.0, 2.5]]) # Step 1: Standardize the data (mean = 0, variance = 1) mean = np.mean(data, axis=0) std_data = data - mean # Step 2: Calculate the covariance matrix cov_matrix = np.cov(std_data, rowvar=False) # Step 3: Calculate the eigenvalues and eigenvectors eigenvalues, eigenvectors = np.linalg.eig(cov_matrix) # Step 4: Sort eigenvalues and eigenvectors sorted_index = np.argsort(eigenvalues)[::-1] sorted_eigenvalues = eigenvalues[sorted_index] sorted_eigenvectors = eigenvectors[:, sorted_index] # Step 5: Select the top k eigenvectors (here we choose k=2) k = 2 eigenvector_subset = sorted_eigenvectors[:, 0:k] # Step 6: Transform the data pca_data = np.dot(std_data, eigenvector_subset) print("Original Data:\n", data) print("Mean:\n", mean) print("Standardized Data:\n", std_data) print("Covariance Matrix:\n", cov_matrix) print("Eigenvalues:\n", eigenvalues) print("Eigenvectors:\n", eigenvectors) print("Sorted Eigenvalues:\n", sorted_eigenvalues) print("Sorted Eigenvectors:\n", sorted_eigenvectors) print("PCA Transformed Data:\n", pca_data) from mpl_toolkits import mplot3d import numpy as np import matplotlib.pyplot as plt fig = plt.figure() # syntax for 3-D projection ax = plt.axes(projection ='3d') # defining axes x = data[:,0] y = data[:,1] z = data[:,2] #https://matplotlib.org/stable/api/_as_gen/matplotlib.pyplot.scatter.html #affichage du nuage de points ax.scatter(x, y, z,marker=".") #affichage du centre de gravité du nuage de points ax.scatter(mean[0], mean[1], mean[2],marker="*") #affichage du vecteur normal au plan #echelle=10 #calcul d'une echelle sympa echelle=np.max(std_data) ax.plot([mean[0],mean[0]+echelle*sorted_eigenvectors[0,2]], [mean[1],mean[1]+echelle*sorted_eigenvectors[1,2]], [mean[2],mean[2]+echelle*sorted_eigenvectors[2,2]]) #print(sorted_eigenvectors[0,2]) ax.axis('equal') #paramètres du plan: a=sorted_eigenvectors[0,2] b=sorted_eigenvectors[1,2] c=sorted_eigenvectors[2,2] #le plan passe par mean -> calcul du paramètre d d=-(a*mean[0]+b*mean[1]+c*mean[2]) print("a:"+str(a)+" b:"+str(b)+" c:"+str(c)+" d:"+str(d)) # syntax for plotting ax.set_title('3d Scatter plot geeks for geeks') plt.show()
Tracé de polygones
- poly.py
import cv2 import numpy as np # Créer une image vide img = np.zeros((512, 512, 3), np.uint8) # Définir les points du polygone pts = np.array([[100, 100], [300, 150], [200, 400], [50, 250]], np.int32) pts = pts.reshape((-1, 1, 2)) # Dessiner et remplir le polygone cv2.fillPoly(img, [pts], (0, 255, 0)) # Afficher l'image cv2.imshow('Image', img) cv2.waitKey(0) cv2.destroyAllWindows()