This is the last version of card manager
This commit is contained in:
parent
c6f997d2ed
commit
9bb26f1310
1 changed files with 245 additions and 0 deletions
245
card_manager/main.py
Normal file
245
card_manager/main.py
Normal file
|
@ -0,0 +1,245 @@
|
|||
from flask import Flask # Pour créer le service
|
||||
from flask import request # Pour faire des jolis "POST"
|
||||
import requests # Pour "request" un server "autre"
|
||||
|
||||
import sqlite3
|
||||
import random as rd
|
||||
import os
|
||||
|
||||
import cv2
|
||||
|
||||
from matplotlib import pyplot
|
||||
import numpy as np
|
||||
|
||||
import json #return json : json.dumps(dico)
|
||||
|
||||
import sqlite3
|
||||
import random as rd
|
||||
import os
|
||||
data_folder = "/data"
|
||||
database_path = "file::memory:?cache=shared"
|
||||
conn = sqlite3.connect(database_path)
|
||||
cursor = conn.cursor()
|
||||
|
||||
cursor.execute("DROP TABLE images")
|
||||
cmd = """CREATE TABLE images
|
||||
(
|
||||
id INT PRIMARY KEY NOT NULL,
|
||||
label VARCHAR(256) NOT NULL,
|
||||
path VARCHAR(256) NOT NULL
|
||||
)"""
|
||||
cursor.execute(cmd)
|
||||
|
||||
|
||||
list_subfolders_with_paths = [f for f in os.scandir(data_folder) if f.is_dir()]
|
||||
idp = 0
|
||||
cmdIns = """INSERT INTO images VALUES (?,?,?)"""
|
||||
for folder in list_subfolders_with_paths:
|
||||
gen = os.scandir(folder)
|
||||
for e in gen:
|
||||
cursor.execute(cmdIns, (idp,folder.name,e.path))
|
||||
idp+=1
|
||||
|
||||
conn.commit()
|
||||
conn.close()
|
||||
|
||||
#prend une liste d'images de même taille et retourne un json décrivant la carte
|
||||
def retourneJSON(Images, eps=5):
|
||||
|
||||
if( len(Images) == 0 ):
|
||||
raise ValueError("Pas d'images reçues")
|
||||
|
||||
d = len(Images[0])
|
||||
n = len(Images)
|
||||
|
||||
#TODO mieux
|
||||
if( n<= 2):
|
||||
card = {"dimX" : n*d + (n+1)*eps,
|
||||
"dimY" : d + 2*eps,
|
||||
"posX" : list(eps+(d/2) + np.array([i*(eps+(d)) for i in range(n)])),
|
||||
"posY" : list(np.array([eps+(d/2) for i in range(n)])),
|
||||
}
|
||||
elif( n<=4 ):
|
||||
card = {"dimX" : 2*d + 3*eps,
|
||||
"dimY" : 2*d + 3*eps,
|
||||
"posX" : list(eps+(d/2) + np.array([i*(eps+(d)) for i in range(2)]))*2,
|
||||
"posY" : list(np.array([eps+(d/2) for i in range(2)])) + list(np.array([eps+d+(d/2) for i in range(2)])),
|
||||
}
|
||||
else:
|
||||
card = {"dimX" : 3*d + 4*eps,
|
||||
"dimY" : 3*d + 4*eps,
|
||||
"posX" : list(eps+(d/2) + np.array([i*(eps+(d)) for i in range(3)]))*3,
|
||||
"posY" : list(np.array([eps+(d/2) for i in range(3)])) + list(np.array([2*eps+d+(d/2) for i in range(3)])) + list(np.array([3*eps+2*d+(d/2) for i in range(3)])),
|
||||
}
|
||||
|
||||
return json.dumps(card) #store json into string ?
|
||||
|
||||
|
||||
|
||||
|
||||
#Generate a card
|
||||
from PIL import Image, ImageDraw
|
||||
import random
|
||||
def generateCard(Img): # Generate a Card with the images in the given order #TODO randomize ?
|
||||
n = len(Img)
|
||||
|
||||
descJSON = retourneJSON(Img)
|
||||
desc = json.loads(descJSON)
|
||||
|
||||
#Read the images
|
||||
Images = []
|
||||
for img in Img:
|
||||
tmp = img# cv2.cvtColor(img, cv2.COLOR_BGR2RGB) #todo plus tard quand on sera fixé
|
||||
Images.append(Image.fromarray(np.uint8(tmp)).convert('RGB'))
|
||||
|
||||
|
||||
#Resize image
|
||||
Size = []
|
||||
image_size = Images[0].size
|
||||
for i in range(len(Images)):
|
||||
scale = random.uniform(0.5, 1)
|
||||
|
||||
Images[i] = Images[i].resize(( int(Images[i].size[0]*scale), int(Images[i].size[1]*scale) ))
|
||||
Size.append(Images[i].size)
|
||||
|
||||
#Rotation
|
||||
for i in range(len(Images)):
|
||||
alpha = random.randint(1, 360)
|
||||
Images[i] = Images[i].rotate(alpha, resample=0, expand=0, fillcolor='white')
|
||||
|
||||
#Card Creation
|
||||
card = Image.new('RGB',(desc["dimX"], desc["dimY"]), (255,255,255)) #white canevas (code final = couleur de background (attention différent du backgroud des images collées dessus))
|
||||
|
||||
#Past images into the card
|
||||
for i in range(len(Images)): #même longueur/ordre : Images, posX, posY
|
||||
card.paste( Images[i], ( int( desc["posX"][i]-Size[i][0]/2 ), int( desc["posY"][i]-Size[i][1]/2 ) ) )
|
||||
#x = int( desc["posX"][i]-Size[i][0]/2 )
|
||||
#y = int( desc["posY"][i]-Size[i][1]/2 )
|
||||
#xmilieu = (x + Images[i].size[0])/2
|
||||
#ymilieu = (y + Images[i].size[1])/2
|
||||
#imgDraw = ImageDraw.Draw(card)
|
||||
#imgDraw.point((xmilieu,ymilieu), fill=(255, 0, 255))
|
||||
|
||||
return card
|
||||
|
||||
|
||||
|
||||
def decoupeDobble(nbIC): #nombre d'images par carte
|
||||
nbC = int(nbIC + 1)
|
||||
nbIT = int((nbIC)*(nbIC+1)/2)
|
||||
return [nbC, nbIT]
|
||||
|
||||
|
||||
|
||||
def coord(M):
|
||||
for i in range(len(M)):
|
||||
for j in range(len(M[0])):
|
||||
if( M[i][j] == 0 ):
|
||||
return [i, j]
|
||||
return -1
|
||||
|
||||
def repartitionNum(nbC, nbTI, nb):
|
||||
#Récupérer nbTI images de classes différentes (2 par classe) dans la BDD et les répartir dans nbC cards de façon correcte
|
||||
repartition = np.zeros((nbC, nb)) #ligne = carte, colonne = class
|
||||
|
||||
#class numéroté de 1 à nbTI
|
||||
for i in range(1, nbTI+1):
|
||||
# On met le nombre une 1ere fois
|
||||
c = coord(repartition)
|
||||
repartition[c[0]][c[1]] = i
|
||||
|
||||
# On met la 2ème itération de ce même nombre
|
||||
p = 0
|
||||
cont = c[1] != 0
|
||||
while(cont):
|
||||
if(repartition[c[0]][c[1]-p] + p == i and repartition[c[0]][c[1]-p] != 0):
|
||||
p += 1
|
||||
else:
|
||||
cont = False
|
||||
p -= 1
|
||||
|
||||
k = 0
|
||||
while( repartition[c[0]+p+1][c[1]-k] != 0 ):
|
||||
k += 1
|
||||
if( k > 2*nb):
|
||||
raise Exception('aucune colonne dispo sur cette ligne')
|
||||
repartition[c[0]+p+1][c[1]-k] = i
|
||||
return repartition
|
||||
|
||||
#TODO avce la BDD : récupérer 2 images de n class déifférentes
|
||||
def recupImage(nbC, nbTI):
|
||||
#selectionner nbTI dossiers au hasard
|
||||
#pour chaque dossier, sélectionner 2 images
|
||||
res = []
|
||||
list_subfolders_with_paths = [f.name for f in os.scandir(data_folder) if f.is_dir() and f.name != 'lost+found' and f.name != "yolo"]
|
||||
rd.shuffle(list_subfolders_with_paths)
|
||||
labels = list_subfolders_with_paths[:nbTI]
|
||||
for label in labels:
|
||||
conn = sqlite3.connect(database_path)
|
||||
cursor = conn.cursor()
|
||||
cursor.execute("SELECT * FROM images WHERE label = ?",(label,))
|
||||
images = cursor.fetchall()
|
||||
path_img1, path_img2 = [img[-1] for img in rd.choices(images,k = 2)]
|
||||
img1,img2 = Image.open(path_img1), Image.open(path_img2)
|
||||
res.append(img1)
|
||||
res.append(img2)
|
||||
return [np.array(e.resize((256,256))) for e in res]
|
||||
|
||||
|
||||
# fait le lien entre la répartition et les images
|
||||
def placerImage(nb):
|
||||
|
||||
nbC, nbTI = decoupeDobble(nb) #nbTI = nb de class donc 2 fois plus d'images car 2 images pour chaque class (nb Total (type) Images), nbC = nb Cartes
|
||||
|
||||
repartition = repartitionNum(nbC, nbTI, nb)
|
||||
images = recupImage(nbC, nbTI) #TODO modifier celon la fct finale
|
||||
|
||||
dico = dict([(i+1, [images[2*i], images[2*i + 1]]) for i in range((nbC))])
|
||||
|
||||
Deck = []
|
||||
for i in range(len(repartition)):
|
||||
ligne = []
|
||||
for j in range(len(repartition[i])):
|
||||
val = int(repartition[i][j])
|
||||
cont = True
|
||||
cnt = 0
|
||||
listDicoVal = list(dico.values())
|
||||
listDicoKey = list(dico.keys())
|
||||
while(cont):
|
||||
#print("val : " + str(val) + "\tcnt : " + str(cnt) + "\tkey : " + str(listDicoKey[cnt]))
|
||||
if(int(val) == int(listDicoKey[cnt])):
|
||||
cont = False
|
||||
|
||||
myValNew = listDicoVal[cnt][-1]
|
||||
myVal = listDicoVal[cnt][0]
|
||||
|
||||
ligne.append(myVal)
|
||||
dico[listDicoKey[cnt]] = [myValNew]
|
||||
else:
|
||||
cnt += 1
|
||||
Deck.append(ligne)
|
||||
|
||||
return Deck
|
||||
|
||||
|
||||
#MS
|
||||
|
||||
app = Flask(__name__)
|
||||
|
||||
#app.config.from_object('config')
|
||||
|
||||
|
||||
@app.route('/recupCarte/<mode>/<nb>', methods=['GET'])
|
||||
def recupCarte(mode, nb): #nb = nb d'images par carte
|
||||
#Ensemble des cartes
|
||||
DeckInitial = placerImage(int(nb))
|
||||
|
||||
Deck = []
|
||||
for Img in DeckInitial:
|
||||
Deck.append(generateCard(Img))
|
||||
|
||||
return json.dumps([np.array(e).tolist() for e in Deck])
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
app.run(host="0.0.0.0",port=50000)
|
Loading…
Reference in a new issue