Table des matières
SAE Vision Industrielle pour les étudiants Formation Initiale
Manip Robotique RubiksCube
Partie vision Projet Rubik's Cube
Dans un premier temps, vous devrez développer l'application réalisant la lecture d'une face du rubik's cube.
Les étapes du traitement sont données ici:
L'image de test à traiter est:
Vous devez spécifier manuellement les coordonnées des 4 coins de la face à traiter:
Vous devez ensuite générer une image rectifiée (par application de l'homographie) de la face du cube avec une résolution de 31×31 pixels:
Vous devez ensuite déterminer pour chacun des pixels de l'image quelle est la couleur (parmi les 6 couleurs apprises) la plus proche et sinon utiliser un autre indice pour indiquer que le pixel n'est d'aucune des 6 couleurs connues:
Vous devez finalement effectuer un vote pour chacune des cases du rubiks cube en utilisant les différentes valeurs calculées précédemment, et générer une image de 3×3 pixels:
Images synthétiques
Fichier pour générer les facettes du cube
- generecube.py
import os import cv2 import numpy as np #tabcolors_python= [[0,2,6,5,5,1,3,2,1],[0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0] ] tabcolors_python= [[5,2,2,4,1,1,6,5,6],[5,2,2,4,1,1,6,5,6],[3,4,4,2,3,5,6,5,6],[5,2,2,4,1,1,6,5,6],[5,2,2,4,1,1,6,5,6],[5,2,2,4,1,1,6,5,6] ] def create_tab_colors(): with open('tab_colors.scad', 'w') as f: f.write('// fichier de définition du cube, a inclure avec:\n') f.write('// include <tab_colors.scad>\n') f.write('// Definition des couleurs\n') f.write('color_black = [0, 0, 0]; // indice 0 \n') f.write('color_white = [1, 1, 1]; // indice 1\n') f.write('color_red = [1, 0, 0]; // indice 2\n') f.write('color_green = [0, 1, 0]; // indice 3\n') f.write('color_orange = [1, 0.5, 0]; // indice 4\n') f.write('color_yellow = [1, 1, 0]; // indice 5\n') f.write('color_blue = [0, 0, 1]; // indice 6\n') f.write('tab_indices_color=[color_black,color_white,color_red,color_green,color_orange,color_yellow,color_blue];\n') f.write('tabcolors= [') for nface in range(6): f.write('[') for ncarre in range(9): #f.write(str(nface)) f.write(str(tabcolors_python[nface][ncarre])) if ncarre!=8: f.write(',') else: f.write(']') if nface!=5: f.write(',') f.write('];') f.close() create_tab_colors()
Fichier modèle 3D du cube
- rubiks.scad
include <tab_colors.scad> // Dimensions du Rubik's Cube cube_size = 26; interieur = 90; interstice = 3; // Fonction pour créer un carré module colored_square(color) { color(color) { square([cube_size, cube_size], true); } } // Fonction pour créer une face du Rubik's cube module face(colors) { for (r = [0:2]) { for (c = [0:2]) { translate([r * (cube_size + interstice), c * (cube_size + interstice), 0]) { colored_square(colors[r][c]); } // Ajout de l'interstice translate([r * (cube_size + interstice) + interstice, c * (cube_size + interstice) + interstice, 0]) { } } } } // Assemblage du Rubik's Cube module rubiks_cube() { translate([-28, -28, 1]) face([[ tab_indices_color[tabcolors [0][0]], tab_indices_color[tabcolors [0][1]], tab_indices_color[tabcolors [0][2]]], [tab_indices_color[tabcolors [0][3]], tab_indices_color[tabcolors [0][4]], tab_indices_color[tabcolors [0][5]]], [tab_indices_color[tabcolors [0][6]], tab_indices_color[tabcolors [0][7]], tab_indices_color[tabcolors [0][8]]]]); //////////////////////////////////////////////////// //pas bon translate([-28, 46, 17]) rotate([90,0,0]) face( [[tab_indices_color[tabcolors [1][0]], tab_indices_color[tabcolors [1][1]], tab_indices_color[tabcolors [1][2]]], [tab_indices_color[tabcolors [1][3]], tab_indices_color[tabcolors [1][4]], tab_indices_color[tabcolors [1][5]]], [tab_indices_color[tabcolors [1][6]], tab_indices_color[tabcolors [1][7]], tab_indices_color[tabcolors [1][8]]]]); //////////////////////////////////////////////////// //pas bon translate([46, -28, 17])rotate([0,-90,0])face([[tab_indices_color[tabcolors [2][0]], tab_indices_color[tabcolors [2][1]], tab_indices_color[tabcolors [2][2]]], [tab_indices_color[tabcolors [2][3]], tab_indices_color[tabcolors [2][4]], tab_indices_color[tabcolors [2][5]]], [tab_indices_color[tabcolors [2][6]], tab_indices_color[tabcolors [2][7]], tab_indices_color[tabcolors [2][8]]]]); //////////////////////////////////////////////////// translate([-28, -44, 17]) rotate([90,0,0]) face([[tab_indices_color[tabcolors [3][0]], tab_indices_color[tabcolors [3][1]], tab_indices_color[tabcolors [3][2]]], [tab_indices_color[tabcolors [3][3]], tab_indices_color[tabcolors [3][4]], tab_indices_color[tabcolors [3][5]]], [tab_indices_color[tabcolors [3][6]], tab_indices_color[tabcolors [3][7]], tab_indices_color[tabcolors [3][8]]]]); //////////////////////////////////////////////////// translate([-44, -28, 17])rotate([0,-90,0]) face([[tab_indices_color[tabcolors [4][0]], tab_indices_color[tabcolors [4][1]], tab_indices_color[tabcolors [4][2]]], [tab_indices_color[tabcolors [4][3]], tab_indices_color[tabcolors [4][4]], tab_indices_color[tabcolors [4][5]]], [tab_indices_color[tabcolors [4][6]], tab_indices_color[tabcolors [4][7]], tab_indices_color[tabcolors [4][8]]]]); //////////////////////////////////////////////////// //pas bon translate([-28, -28,91]) face( [[tab_indices_color[tabcolors [5][0]], tab_indices_color[tabcolors [5][1]], tab_indices_color[tabcolors [5][2]]], [tab_indices_color[tabcolors [5][3]], tab_indices_color[tabcolors [5][4]], tab_indices_color[tabcolors [5][5]]], [tab_indices_color[tabcolors [5][6]], tab_indices_color[tabcolors [5][7]], tab_indices_color[tabcolors [5][8]]]]); //////////////////////////////////////////////////// } module black_cube(color) { color([0, 0, 0]) { translate([1,1,46]) cube([interieur, interieur, interieur],center = true); } } // Appel de la fonction pour générer le cube noir black_cube(); rubiks_cube();
Fichier pour générer une image
import os import cv2 import numpy as np filename_img="img" #executable_openscad="openscad" executable_openscad="D:\openscad-2021.01\openscad.exe" chaine=f'{executable_openscad} -o {filename_img}.png --imgsize=1024,768 --camera=230,340,500,0,0,0 --projection=p rubiks.scad' os.system(chaine)
Images Réelles
Pleins d'images à utiliser: https://bvdp.inetdoc.net/files/iut/vision_BUT3/
Archive zip des images: https://bvdp.inetdoc.net/files/iut/vision_BUT3/images_rubiks.zip