Skip to content
Snippets Groups Projects
Commit d2d8c64e authored by Lucas Philippe's avatar Lucas Philippe
Browse files

modification ré échantillonnage et détection des mots recommandés

parent 2bca65f8
No related branches found
No related tags found
No related merge requests found
......@@ -3,3 +3,4 @@ import os
DATA_DIR = os.path.dirname(os.path.abspath(__file__))
LAYOUT_FILE = os.path.join(DATA_DIR, 'layout.json')
MOTS_FILE = os.path.join(DATA_DIR, 'mots.txt')
This diff is collapsed.
......@@ -4,10 +4,12 @@ class Key:
def __init__(self, x, y, keyWidth, keyHeight, keySpacing, width, symbol):
self.x = x * (keyWidth + keySpacing)
self.y = y * (keyHeight + keySpacing)
self.position = QPoint(self.x, self.y)
self.symbol = symbol
self.rect = QRect(self.x, self.y, width * (keyWidth + keySpacing) - keySpacing, keyHeight)
self.rect = QRect(self.x, self.y, (width * (keyWidth + keySpacing) - keySpacing), keyHeight)
def isOver(self, point):
return self.rect.contains(point)
\ No newline at end of file
adjustedRect = self.rect.adjusted(5, 5, -5, -5)
return adjustedRect.contains(point)
def getCenter(self):
return self.rect.center()
class Mot:
def __init__(self, word: str, stroke: list, distance: int):
self.word = word
self.stroke = stroke
self.distance = distance
class Dictionnaire:
def __init__(self):
self.words = dict()
for letter in list(map(chr, range(97, 123))):
self.words[letter] = []
def addWord(self, word: str, stroke: list, distance: int):
# get first letter of word
letter = word[0]
self.words[letter].append(Mot(word, stroke, distance))
import numpy as np
def find_distance(s, t):
len_s, len_t = len(s), len(t)
DTW = np.zeros((len_s + 1, len_t + 1))
DTW[1:, 0] = np.inf
DTW[0, 1:] = np.inf
for i in range(1, len_s + 1):
for j in range(1, len_t + 1):
cost = abs(s[i - 1][1] - t[j - 1][1]) + abs(s[i - 1][0] - t[j - 1][0])
min_val = min(DTW[i - 1, j], DTW[i, j - 1], DTW[i - 1, j - 1])
DTW[i, j] = cost + min_val
return DTW[len_s, len_t]
class DwtAlgo:
def __init__(self, nb_of_words, dictionary):
self.nb_of_words = nb_of_words
self.dictionary = dictionary
def compare_to_dictionary(self, s, first_letter):
min_distances = [np.inf] * self.nb_of_words
best_words = [None] * self.nb_of_words
for template in self.dictionary.words[first_letter]:
distance = find_distance(s, template.stroke)
for i in range(3):
if distance < min_distances[i]:
min_distances[i+1:] = min_distances[i:-1]
min_distances[i] = distance
best_words[i+1:] = best_words[i:-1]
best_words[i] = template.word
break
return best_words
import math
def interpolate(firstPoint, secondPoint, distance):
ab = math.sqrt((secondPoint[0] - firstPoint[0]) ** 2 + (secondPoint[1] - firstPoint[1]) ** 2)
x = firstPoint[0] + (secondPoint[0] - firstPoint[0]) * distance / ab
y = firstPoint[1] + (secondPoint[1] - firstPoint[1]) * distance / ab
return int(x), int(y)
def resample(listOfPoints, d):
if len(listOfPoints) == 0:
return []
newListOfPoints = [listOfPoints[0]]
idx = 1
def interpolate(a, b, d):
ax, ay = a
bx, by = b
ab_dist = math.sqrt((bx - ax) ** 2 + (by - ay) ** 2)
ratio = d / ab_dist
return ax + ratio * (bx - ax), ay + ratio * (by - ay)
currentDistance = 0
while idx < len(listOfPoints):
firstPoint = listOfPoints[idx - 1]
secondPoint = listOfPoints[idx]
currentDistance += math.sqrt((secondPoint[0] - firstPoint[0]) ** 2 + (secondPoint[1] - firstPoint[1]) ** 2)
def resample(stroke, d):
if not stroke:
return []
if currentDistance >= d:
newPoint = interpolate(firstPoint, secondPoint, d - currentDistance)
newListOfPoints.append(newPoint)
currentDistance = 0
idx += 1
resampled = [stroke[0]]
remaining_distance = d
return newListOfPoints
for i in range(1, len(stroke)):
current_point = stroke[i - 1]
next_point = stroke[i]
distance = math.sqrt((next_point[0] - current_point[0]) ** 2 + (next_point[1] - current_point[1]) ** 2)
if (distance >= remaining_distance):
new_point = interpolate(current_point, next_point, remaining_distance)
resampled.append(new_point)
stroke.insert(i, new_point)
remaining_distance = d
else:
remaining_distance -= distance
return resampled
from PyQt5.QtWidgets import QWidget, QLineEdit, QVBoxLayout
from src.widgets.KeyboardWidget import KeyboardWidget
from PySide6.QtCore import Slot
# from PySide6.QtCore import Slot # This line might not be necessary unless you're using it elsewhere
class EditeurWindow(QWidget):
def __init__(self):
super().__init__()
self.setWindowTitle('Editeur')
# Création des widgets
line_edit = QLineEdit(self)
# Define line_edit as an attribute of the class
self.line_edit = QLineEdit(self)
keyboard_widget = KeyboardWidget()
# Création du layout et ajout des widgets
layout = QVBoxLayout()
layout.addWidget(line_edit)
layout.addWidget(self.line_edit) # Use self.line_edit here
layout.addWidget(keyboard_widget)
self.setLayout(layout)
# Connexion su dignal
keyboard_widget.newletter.connect(line_edit.insert)
# Connexion du signal
keyboard_widget.newletter.connect(self.addCharacter)
def addCharacter(self, character):
currentText = self.line_edit.text() # This should work now
# Add a space only if "character" is more than one letter (meaning it's a word)
if len(character) > 1:
newText = currentText + character + ' '
else:
newText = currentText + character
self.line_edit.setText(newText)
......@@ -3,9 +3,10 @@ import json
from PyQt5.QtCore import Qt, QSize, QPoint, pyqtSignal
from PyQt5.QtGui import QPainter, QColor, QPen
from PyQt5.QtWidgets import QWidget
from documents.FileDefinition import LAYOUT_FILE
from documents.FileDefinition import LAYOUT_FILE, MOTS_FILE
from src.model.Key import Key
from PySide6.QtCore import Signal
from src.module.Dictionnaire import Dictionnaire
from src.module.Dwt_algo import DwtAlgo
from src.module.Reconnaisseur import resample
DEFAULT_COLOR = QColor("white")
......@@ -17,10 +18,16 @@ PEN_COLOR2 = QColor(255, 0, 0, 255)
PEN_WIDTH = 5
WordSelectorHeight = 0
distanceStroke = 50
class KeyboardWidget(QWidget):
newletter = pyqtSignal(str)
def __init__(self):
super().__init__()
self.dwt = None
self.letter_selected = None
self.keys = []
self.keyWidth = None
self.keyHeight = None
......@@ -30,13 +37,25 @@ class KeyboardWidget(QWidget):
self.keyboardHeight = 0
self.trace = []
self.resampledTrace = []
self.nbReco = 0
self.mousePos = QPoint(0,0)
self.pressedKey = None
self.wordSelectors = []
# Initialiser le clavier
self.loadLayoutJson()
self.setMouseTracking(True)
# Initialiser le dictionnaire
self.dictionnaire = Dictionnaire()
self.initDictionnaire()
# Initialiser le wordSelector
self.initWordSelector()
self.update()
def loadLayoutJson(self):
......@@ -46,6 +65,7 @@ class KeyboardWidget(QWidget):
# Accéder aux paramètres
self.nbReco = layout_clavier['nbReco']
self.keyWidth = layout_clavier['keyWidth']
self.keyHeight = layout_clavier['keyHeight']
self.keySpacing = layout_clavier['keySpacing']
......@@ -54,8 +74,29 @@ class KeyboardWidget(QWidget):
for keyData in layout_clavier['keys']:
self.keys.append(self.createKey(keyData))
# Créer les touches de selection de mot
# word_selector_key_width = 10 / self.nbReco
word_selector_key_width = 2.5
print(word_selector_key_width)
for i in range(self.nbReco):
key = Key(i * word_selector_key_width, 0, self.keyWidth, self.keyHeight, self.keySpacing, word_selector_key_width, '')
self.wordSelectors.append(key)
self.keys.insert(0, key)
def initWordSelector(self):
self.dwt = DwtAlgo(self.nbReco, self.dictionnaire)
def initDictionnaire(self):
with open(MOTS_FILE, "r") as file:
lines = file.readlines()
for line in lines:
word = line.strip()
self.wordToStroke(word, distanceStroke)
def createKey(self, keyData):
key = Key(keyData['x'], keyData['y'], self.keyWidth, self.keyHeight, self.keySpacing, keyData['width'], keyData['symbol'])
key = Key(keyData['x'], keyData['y'] + WordSelectorHeight, self.keyWidth, self.keyHeight, self.keySpacing, keyData['width'], keyData['symbol'])
bottomRightPoint = key.rect.bottomRight()
currentHeight = bottomRightPoint.y() + self.keySpacing
currentWidth = bottomRightPoint.x() + self.keySpacing
......@@ -101,19 +142,49 @@ class KeyboardWidget(QWidget):
self.update()
def mousePressEvent(self, event):
position = event.pos()
self.trace.append((position.x(), position.y()))
for key in self.keys:
if key.isOver(self.mousePos):
self.pressedKey = key
self.letter_selected = key.symbol
return
def mouseReleaseEvent(self, event):
position = event.pos()
self.resampledTrace.append((position.x(), position.y()))
for key in self.keys:
if key.isOver(self.mousePos):
if key == self.pressedKey:
self.pressedKey = None
self.newletter.emit(key.symbol)
if len(key.symbol) > 1:
for key_selector in self.wordSelectors:
key_selector.symbol = ''
self.clearTrace()
return
elif len(key.symbol) == 0:
self.clearTrace()
return
break
else:
break
# Nouvelle section: Imprimer les lettres sélectionnées par le tracé ré-échantillonné
print("Lettres sélectionnées par le tracé ré-échantillonné :")
selected_symbols = set() # Utiliser un ensemble pour éviter les duplicatas
for point in self.resampledTrace:
for key in self.keys:
if key.isOver(QPoint(*point)):
if key.symbol not in selected_symbols: # Pour éviter de réimprimer les mêmes symboles
print(key.symbol, end=' ')
selected_symbols.add(key.symbol)
print() # Pour le retour à la ligne après l'impression des symboles
best_words = self.dwt.compare_to_dictionary(self.resampledTrace, self.letter_selected)
for i in range(len(best_words)):
self.wordSelectors[i].symbol = best_words[i]
self.clearTrace()
def paintKey(self, painter, key, color):
......@@ -133,7 +204,22 @@ class KeyboardWidget(QWidget):
if self.pressedKey is not None:
point = (self.mousePos.x(), self.mousePos.y())
self.trace.append(point)
self.resampledTrace = resample(self.trace, 50)
self.resampledTrace = resample(self.trace, distanceStroke)
self.update()
def wordToStroke(self, word: str, d: int):
strokes = []
for letter in word:
for key in self.keys:
if key.symbol == letter:
point = key.getCenter()
strokes.append((point.x(), point.y()))
break
# Ajouter le mot au dictionnaire
resampledTrace = resample(strokes, d)
self.dictionnaire.addWord(word, resampledTrace, d)
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment