Table des matières

SAE Vision Industrielle pour les étudiants Formation Initiale

Manip Robotique RubiksCube

https://www.youtube.com/embed/mFfiV3QRtU8

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:

Image 0: bvdp.inetdoc.net_files_iut_tp_lpro_vision_rubiks.jpg

Vous devez spécifier manuellement les coordonnées des 4 coins de la face à traiter:

Image 1:

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:

Image 2:

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:

Image 3:

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:

Image 4:

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