Pour les matheux ..se contruire un mini OCR
- Kwai chang caine
- Messages : 6989
- Inscription : sam. 23/sept./2006 18:32
- Localisation : Isere
Pour les matheux ..se contruire un mini OCR
Bonjour à tous,
Voila j'aimerais essayer de me faire un petit code qui essaie de reconnaître les lettres et chiffres d'une image.
En fait pour simplifier les choses, j'avais pensé couper les phrases en minuscules images ne contenant qu'une seule petite lettre.
Je me suis dit que ce serait peut être plus rapide et facile
Donc, je me retrouve avec une image en BMP et je voudrais essayer de lire pixel/pixel pour essayer de savoir quelle lettre c'est.
Quelqu'un a des idées de départ, y'a t'il un algo de matheu comme j'en connait pas pour effectuer cette tache...
Ce qui facilite ma tache c'est que la police est toujours la même, par contre elle est pas toujours de la même taille c'est ce qui complique l'affaire.
J'avais essayé avec ce code de DarkDragon qui marche super bien
http://www.purebasic.fr/english/viewtop ... 78#p374278
Mais comme les caractères n'ont pas la même taille, le code ne retrouve pas un "2" par exemple si il est 1% plus gros ou autre
J'ai essayé le resize mais apparemment ça doit déformer l'image légèrement et le code ne reconnait que les "1", normal, un 1 plus petit c'est toujours une barre
Alors j'en sais rien, peut etre mettre le caractère a rechercher dans une matrice, et le caractère témoin dans une autre...et comparer les tableaux..c'est ma première idée
Merci et bonne journée
Voila j'aimerais essayer de me faire un petit code qui essaie de reconnaître les lettres et chiffres d'une image.
En fait pour simplifier les choses, j'avais pensé couper les phrases en minuscules images ne contenant qu'une seule petite lettre.
Je me suis dit que ce serait peut être plus rapide et facile
Donc, je me retrouve avec une image en BMP et je voudrais essayer de lire pixel/pixel pour essayer de savoir quelle lettre c'est.
Quelqu'un a des idées de départ, y'a t'il un algo de matheu comme j'en connait pas pour effectuer cette tache...
Ce qui facilite ma tache c'est que la police est toujours la même, par contre elle est pas toujours de la même taille c'est ce qui complique l'affaire.
J'avais essayé avec ce code de DarkDragon qui marche super bien
http://www.purebasic.fr/english/viewtop ... 78#p374278
Mais comme les caractères n'ont pas la même taille, le code ne retrouve pas un "2" par exemple si il est 1% plus gros ou autre
J'ai essayé le resize mais apparemment ça doit déformer l'image légèrement et le code ne reconnait que les "1", normal, un 1 plus petit c'est toujours une barre
Alors j'en sais rien, peut etre mettre le caractère a rechercher dans une matrice, et le caractère témoin dans une autre...et comparer les tableaux..c'est ma première idée
Merci et bonne journée
Re: Pour les matheux ..se contruire un mini OCR
je vais faire comme sph, de l'ultra condensé : perceptron
- Mindphazer
- Messages : 695
- Inscription : mer. 24/août/2005 10:42
Re: Pour les matheux ..se contruire un mini OCR
Bureau : Win10 64bits
Maison : Macbook Pro M3 16" SSD 512 Go / Ram 24 Go - iPad Pro 32 Go (pour madame) - iPhone 15 Pro Max 256 Go
Maison : Macbook Pro M3 16" SSD 512 Go / Ram 24 Go - iPad Pro 32 Go (pour madame) - iPhone 15 Pro Max 256 Go
-
- Messages : 2194
- Inscription : jeu. 27/janv./2005 19:07
Re: Pour les matheux ..se contruire un mini OCR
Pour tester ses résultats: système d'OCR gratuit en ligne! 
http://www.free-ocr.com/
... et vous verrez que le système de Captcha du lien ci-dessus est aussi un système de reconnaissance de caractères, mais là c'est vous le système de reconnaissance!
la théorie!
http://www.youtube.com/watch?v=-Ht4qiDRZE8

http://www.free-ocr.com/
... et vous verrez que le système de Captcha du lien ci-dessus est aussi un système de reconnaissance de caractères, mais là c'est vous le système de reconnaissance!

la théorie!
http://www.youtube.com/watch?v=-Ht4qiDRZE8
Re: Pour les matheux ..se contruire un mini OCR
Bonjour KCC,
il y à de ça 3 mois j'ai codé un truc pour tester mes connaissances de cours pour un cours de modélisation avancée avec des réseaux de neurones.
Ca ne fonctionne pas super, et l'apprentissage n'est pas forcé d'arriver à un résultat mais voila :
En gros tu créés ta base d'exemple a apprendre, ensuite tu définies la taille du réseau de neurone, puis tu effectues l'apprentissage jusqu'à ce que les résultats soient acceptables.
En fin de compte tu peux dégrader les exemples de la base d'apprentissage et regarder si le réseau les reconstruit correctement... Ce n'est pas vraiment de l'ocr, mais plutôt un début.
Un des problèmes des ces techniques d'ocr consiste à isolé les caractères pour les soumettre à l’algorithme de reconnaissance.
C'est complexe, et il faut plein d'hypothèse sur la position des caractères etc... Il y a un paquet de théorie à maitriser avant.
il y à de ça 3 mois j'ai codé un truc pour tester mes connaissances de cours pour un cours de modélisation avancée avec des réseaux de neurones.
Ca ne fonctionne pas super, et l'apprentissage n'est pas forcé d'arriver à un résultat mais voila :
En gros tu créés ta base d'exemple a apprendre, ensuite tu définies la taille du réseau de neurone, puis tu effectues l'apprentissage jusqu'à ce que les résultats soient acceptables.
En fin de compte tu peux dégrader les exemples de la base d'apprentissage et regarder si le réseau les reconstruit correctement... Ce n'est pas vraiment de l'ocr, mais plutôt un début.
Un des problèmes des ces techniques d'ocr consiste à isolé les caractères pour les soumettre à l’algorithme de reconnaissance.
C'est complexe, et il faut plein d'hypothèse sur la position des caractères etc... Il y a un paquet de théorie à maitriser avant.
Code : Tout sélectionner
UsePNGImageDecoder()
UsePNGImageEncoder()
;{ structure
CompilerIf #PB_Compiler_OS <> #PB_OS_Windows
#White = 16777215
CompilerEndIf
Structure BaseApprentissage_Exemple
List Entree.l()
EndStructure
Structure BaseApprentissage
List Exemple.BaseApprentissage_Exemple()
NombreEntree.l
IS_Memory.b
EndStructure
Structure Neurone
List PoidsEntree.d()
Seuil.d
IS_Memory.b
EndStructure
Structure MemoireAssociative
List Neurone.Neurone()
IS_Memory.b
EndStructure
;}
;{ variables
Global WD_Window_0
Global GD_ListIcon_0
Global GD_Image_0, GD_Image_1
Global GD_Text_0, GD_Text_1, GD_Text_2, GD_Text_3, GD_Text_4, GD_Text_5, GD_Text_6, GD_Text_7, GD_Text_8, GD_Text_9
Global GD_Frame3D_0, GD_Frame3D_1, GD_Frame3D_2
Global GD_Button_0, GD_Button_1, GD_Button_2, GD_Button_3, GD_Button_4, GD_Button_5, GD_Button_6
Global GD_String_0, GD_String_1, GD_String_2, GD_String_3, GD_String_4, GD_String_5, GD_String_6
Global GD_Canvas_0
Global GD_Editor_0
Global IMG_canvas.l, Canvas_RATIO.d, Canvas_W, Canvas_H
;}
;{ macro générale
Macro Message(Message)
AddGadgetItem(GD_Editor_0, 0, "[" + FormatDate("%hh:%ii:%ss", Date()) + "] - " + Message)
EndMacro
;}
;{ procedures neuronales
EnableExplicit
Procedure.i CreationBaseApprentissage(NombreEntree.l, *NouvelleBase.BaseApprentissage = 0)
Protected IS_memory.b
If *NouvelleBase = 0
*NouvelleBase = AllocateMemory(SizeOf(BaseApprentissage))
IS_memory = #True
EndIf
InitializeStructure(*NouvelleBase, BaseApprentissage)
*NouvelleBase\IS_Memory = IS_memory
*NouvelleBase\NombreEntree = NombreEntree
ProcedureReturn *NouvelleBase
EndProcedure
Procedure FreeBaseApprentissage(*Base.BaseApprentissage)
ForEach *base\Exemple()
FreeList(*Base\Exemple()\Entree())
Next
FreeList(*Base\Exemple())
If *Base\IS_Memory
FreeMemory(*Base)
EndIf
EndProcedure
Procedure Ajout_Exemple_Apprentissage(*Base.BaseApprentissage, Image)
Protected x.l, y.l
If IsImage(Image) = 0
Message("ERREUR Ajout Exemple d'apprentissage : l'image n'est pas correctement initialisée")
ProcedureReturn #False
EndIf
If *Base\NombreEntree <> ImageWidth(Image) * ImageHeight(Image)
Message("ERREUR Ajout Exemple d'apprentissage : Le nb d'entrée est différent du produit W*H de l'image")
ProcedureReturn #False
EndIf
AddElement(*Base\Exemple())
InitializeStructure(*Base\Exemple(), BaseApprentissage_Exemple)
If StartDrawing(ImageOutput(Image))
For x = 0 To ImageWidth(Image) - 1
For y = 0 To ImageHeight(Image) - 1
AddElement(*Base\Exemple()\Entree())
If Point(x, y) = 0 ; noir
*Base\Exemple()\Entree() = -1
Else
*Base\Exemple()\Entree() = 1
EndIf
Next
Next
StopDrawing()
EndIf
ProcedureReturn #True
EndProcedure
Procedure.i CreationNeurone(NombreEntree.l, Seuil.d, Hazard.b, *NouveauNeurone.Neurone = 0)
Protected i, IS_memory.b
If *NouveauNeurone = 0
*NouveauNeurone = AllocateMemory(SizeOf(Neurone))
IS_memory = #True
EndIf
InitializeStructure(*NouveauNeurone, Neurone)
*NouveauNeurone\Seuil = Seuil
*NouveauNeurone\IS_Memory = IS_memory
For i = 1 To NombreEntree
AddElement(*NouveauNeurone\PoidsEntree())
If Hazard
*NouveauNeurone\PoidsEntree() = (Random(20) - 10) / 10
EndIf
Next
ProcedureReturn *NouveauNeurone
EndProcedure
Procedure FreeNeurone(*Neurone.Neurone)
FreeList(*Neurone\PoidsEntree())
If *Neurone\IS_Memory
FreeMemory(*Neurone)
EndIf
EndProcedure
;{ Mono Neurone
; Procedure Apprentissage_MonoNeurone(*Neurone.Neurone, *Base.BaseApprentissage, correcteur_nu.d, IterationMaximum.l = 100)
; Protected PasdErreur.b, SortieObtenue.d, x.b, Iteration.l
;
; Repeat
; PasdErreur = #True
;
; ForEach *Base\Exemple()
; SortieObtenue = - *Neurone\Seuil
;
; If ListSize(*Neurone\PoidsEntree()) <> ListSize(*Base\Exemple()\Entree())
; Debug "ERREUR : Nombre d'entrée différents du nombre de poids"
; ProcedureReturn #False
; EndIf
;
; ResetList(*Neurone\PoidsEntree())
; ForEach *Base\Exemple()\Entree()
; NextElement(*Neurone\PoidsEntree())
; SortieObtenue = SortieObtenue + *Neurone\PoidsEntree() * *base\Exemple()\Entree()
; Next
;
; If SortieObtenue > 0
; x = 1
; Else
; x = -1
; EndIf
;
; Debug "Exemple " + Str(ListIndex(*base\Exemple()) + 1) + " : x = " + Str(x) + " Sortie désirée = " + *base\Exemple()\Sortie_desiree + " Obtenue = " + SortieObtenue
;
; If x <> *Base\Exemple()\Sortie_desiree
; ; modification des poids
; PasdErreur = #False
;
; Debug "Modification des poids :"
;
; ResetList(*Base\Exemple()\Entree())
; ForEach *Neurone\PoidsEntree()
; NextElement(*Base\Exemple()\Entree())
; *Neurone\PoidsEntree() = *Neurone\PoidsEntree() + correcteur_nu * *Base\Exemple()\Entree() * (*base\Exemple()\Sortie_desiree - x)
;
; Debug "w" + Str(ListIndex(*Neurone\PoidsEntree())+1) + " = " + *Neurone\PoidsEntree()
; Next
; ; correction du seuil pour une convergence plus rapide
; *Neurone\Seuil = *Neurone\Seuil - correcteur_nu * (*base\Exemple()\Sortie_desiree - x)
; Debug "Seuil = " + *Neurone\Seuil
;
; Else
; ; rien, on passe à l'exemple suivant !
; EndIf
;
; Next
;
; Iteration + 1
; Until PasdErreur = #True Or Iteration >= IterationMaximum
;
; ProcedureReturn PasdErreur
; EndProcedure
;
; Procedure Reponse_MonoNeurone(*Neurone.Neurone, Sequence$)
; Protected SortieObtenue.d, Nb.l
;
; Nb = CountString(Sequence$, ",")
;
; If Nb + 1 <> ListSize(*Neurone\PoidsEntree())
; ProcedureReturn 0 ; pas de calcul
; EndIf
;
; SortieObtenue = - *Neurone\Seuil
; ForEach *Neurone\PoidsEntree()
; SortieObtenue = SortieObtenue + *Neurone\PoidsEntree() * Val(StringField(Sequence$, ListIndex(*Neurone\PoidsEntree()) + 1, ","))
; Next
;
; If SortieObtenue > 0
; ProcedureReturn 1
; Else
; ProcedureReturn -1
; EndIf
; EndProcedure
;
;}
Procedure.i CreationMemoireAssociative(NombreNeurones, NombreEntreeParNeurone, *NouvelleMemoireAssociative.MemoireAssociative = 0)
Protected i, IS_memory.b
If *NouvelleMemoireAssociative = 0
*NouvelleMemoireAssociative = AllocateMemory(SizeOf(MemoireAssociative))
IS_memory = #True
EndIf
InitializeStructure(*NouvelleMemoireAssociative, MemoireAssociative)
*NouvelleMemoireAssociative\IS_Memory = IS_memory
For i = 1 To NombreNeurones
AddElement(*NouvelleMemoireAssociative\Neurone())
CreationNeurone(NombreEntreeParNeurone, 0, #False, *NouvelleMemoireAssociative\Neurone())
Next
Message("Memoire Associative Créée - " + Str(NombreNeurones) + " Neurones à " + Str(NombreEntreeParNeurone) + " Entrées")
ProcedureReturn *NouvelleMemoireAssociative
EndProcedure
Procedure FreeMemoireAssociative(*MemoireAssociative.MemoireAssociative)
ForEach *MemoireAssociative\Neurone()
FreeNeurone(*MemoireAssociative\Neurone())
Next
FreeList(*MemoireAssociative\Neurone())
If *MemoireAssociative\IS_Memory
FreeMemory(*MemoireAssociative)
EndIf
EndProcedure
Procedure Apprentissage_MemoireAssociative(*MemoireAssociative.MemoireAssociative, *Base.BaseApprentissage, Pas_ModificationPoids.d = 0.2, CycleOut = 100)
Protected Erreur, Resultat.d, x_bool.b, entre_bool.b, Cycle.l, time, text$
Protected res.l ;, avant.d
FirstElement(*MemoireAssociative\Neurone())
If ListSize(*MemoireAssociative\Neurone()\PoidsEntree()) <> *base\NombreEntree
Message("ERREUR : Le nombre des entrées de la Base d'apprentissage n'est pas celui prévu pour cette mémoire.")
ProcedureReturn -1
EndIf
; initialisation des poids
ForEach *MemoireAssociative\Neurone()
ForEach *MemoireAssociative\Neurone()\PoidsEntree()
*MemoireAssociative\Neurone()\PoidsEntree() = 0 ; (-Random(20) + 10) / 100
Next
*MemoireAssociative\Neurone()\Seuil = 2
Next
Message("######## Début de l'apprentissage")
time = ElapsedMilliseconds()
Protected NewList erreur()
Repeat
Erreur = #False
Cycle + 1
If ElapsedMilliseconds() - time > 500
While WindowEvent() : Wend
time = ElapsedMilliseconds()
EndIf
Message("## Cycle : " + Str(Cycle))
ForEach *Base\Exemple()
Message("## # Exemple : " + Str(ListIndex(*Base\Exemple())))
ClearList(erreur())
ForEach *MemoireAssociative\Neurone()
; Message("## # # Neurone : " + Str(ListIndex(*MemoireAssociative\Neurone())))
Resultat = - *MemoireAssociative\Neurone()\Seuil
ResetList(*Base\Exemple()\Entree())
ForEach *MemoireAssociative\Neurone()\PoidsEntree()
NextElement(*Base\Exemple()\Entree())
Resultat = Resultat + *Base\Exemple()\Entree() * *MemoireAssociative\Neurone()\PoidsEntree()
Next
If Resultat > 0
x_bool = 1
Else
x_bool = -1
EndIf
; test du résultat par rapport à l'état voulu :
SelectElement(*base\Exemple()\Entree(), ListIndex(*MemoireAssociative\Neurone())) ; correspondance Neurone / Entrée
; Message("Etat = " + Str(x_bool) + " Sortie désirée = " + Str(entre_bool))
If x_bool <> *base\Exemple()\Entree() ; Erreur, on procède à la correction de la valeur des Poids
Erreur = #True
; Message("Correction")
AddElement(erreur())
erreur() = ListIndex(*MemoireAssociative\Neurone())
ResetList(*base\Exemple()\Entree())
ForEach *MemoireAssociative\Neurone()\PoidsEntree()
NextElement(*Base\Exemple()\Entree())
*MemoireAssociative\Neurone()\PoidsEntree() = *MemoireAssociative\Neurone()\PoidsEntree() - Pas_ModificationPoids * *Base\Exemple()\Entree() * x_bool
Next
EndIf
Next
text$ = ""
ForEach erreur()
text$ = text$ + ", " + Str(erreur())
Next
Message("Neurones corrigés : " + Mid(text$, 3, Len(text$)))
Next
Until Erreur = #False Or Cycle >= CycleOut
Message("######## Fin de l'apprentissage")
If erreur = #False
ProcedureReturn 0
EndIf
ProcedureReturn Cycle
EndProcedure
Procedure CalculReponse(*MemoireAssociative.MemoireAssociative, Image)
Protected x.l, y.l, Resultat.d, x_bool.b, Image_res
If IsImage(Image) = 0
Message("ERREUR Calcul Réponse : l'image n'est pas correctement initialisée")
ProcedureReturn -1
EndIf
FirstElement(*MemoireAssociative\Neurone())
If ListSize(*MemoireAssociative\Neurone()\PoidsEntree()) <> ImageWidth(Image) * ImageHeight(Image)
Message("ERREUR Calcul Réponse : Le nb d'entrée est différent du produit W*H de l'image")
ProcedureReturn -1
EndIf
Protected NewList Image()
If StartDrawing(ImageOutput(Image))
For x = 0 To ImageWidth(Image) - 1
For y = 0 To ImageHeight(Image) - 1
AddElement(Image())
If Point(x, y) = 0 ; noir
Image() = -1
Else
Image() = 1
EndIf
Next
Next
StopDrawing()
EndIf
Protected NewList Image_res()
ForEach *MemoireAssociative\Neurone()
; Message("## # # Neurone : " + Str(ListIndex(*MemoireAssociative\Neurone())))
Resultat = - *MemoireAssociative\Neurone()\Seuil
ResetList(Image())
ForEach *MemoireAssociative\Neurone()\PoidsEntree()
NextElement(Image())
Resultat = Resultat + Image() * *MemoireAssociative\Neurone()\PoidsEntree()
Next
If Resultat > 0
x_bool = 1
Else
x_bool = -1
EndIf
AddElement(Image_res())
Image_res() = x_bool
Next
Image_res = CreateImage(#PB_Any, ImageWidth(Image), ImageHeight(Image))
ResetList(Image_res())
StartDrawing(ImageOutput(Image_res))
For x = 0 To ImageWidth(Image) - 1
For y = 0 To ImageHeight(Image) - 1
NextElement(Image_res())
If Image_res() = -1 ; noir
Plot(x, y, 0)
Else
Plot(x, y, #White)
EndIf
Next
Next
StopDrawing()
ProcedureReturn Image_res
EndProcedure
;}
;{ procedure interface
Procedure ChargementImageDATA(file$); retourne le nb d'images chargées
Protected file_ID, nb, erreur, i, taille, *mem, img_ID, Nom$
file_ID = OpenFile(#PB_Any, file$)
If file_ID = 0
MessageRequester("Chargement des données Image", "Le fichier " + file$ + " n'a pu être ouvert." + #CR$ + "Rien n'a été chargé")
ProcedureReturn #False
EndIf
ClearGadgetItems(GD_ListIcon_0)
nb = ReadLong(file_ID)
For i = 1 To nb
taille = ReadLong(file_ID)
If taille = 0
erreur + 1
Else
*mem = AllocateMemory(taille, #PB_Memory_NoClear)
If *mem = 0
erreur + 1
Else
Nom$ = ReadString(file_ID)
ReadData(file_ID, *mem, taille)
img_ID = CatchImage(#PB_Any, *mem)
FreeMemory(*mem)
If img_ID = 0
erreur + 1
Else
AddGadgetItem(GD_ListIcon_0, -1, Nom$, ImageID(img_ID))
SetGadgetItemData(GD_ListIcon_0, CountGadgetItems(GD_ListIcon_0) - 1, img_ID)
EndIf
EndIf
EndIf
Next
CloseFile(file_ID)
ProcedureReturn nb - erreur
EndProcedure
Procedure SauvegardeImageDATA(file$)
Protected nb, file_ID, i, *mem, erreur, img
file_ID = CreateFile(#PB_Any, file$)
If file_ID = 0
MessageRequester("Sauvegarde des Données Images", "Impossible de créer le fichier" + #CR$ + file$)
ProcedureReturn #False
EndIf
; écriture du nb d'image
nb = CountGadgetItems(GD_ListIcon_0) - 1
WriteLong(file_ID, nb + 1)
For i = 0 To nb
img = GetGadgetItemData(GD_ListIcon_0, i)
If IsImage(img) = 0
erreur + 1
Else
*mem = EncodeImage(img, #PB_ImagePlugin_PNG)
If *mem = 0
erreur + 1
Else
WriteLong(file_ID, MemorySize(*mem))
WriteStringN(file_ID, GetGadgetItemText(GD_ListIcon_0, i))
WriteData(file_ID, *mem, MemorySize(*mem))
EndIf
EndIf
Next
; on tient compte des erreurs de sauvegarde possibles
FileSeek(file_ID, 0)
WriteLong(file_ID, nb + 1 - erreur)
CloseFile(file_ID)
ProcedureReturn nb + 1 - erreur
EndProcedure
Procedure MiseAJour_TailleCanvas(NePasToucherImage = #False)
Protected w, h, ratio.d, Canvas_0_w, Canvas_0_h
;{ taille et protections
w = Val(GetGadgetText(gd_string_2))
h = Val(GetGadgetText(GD_String_3))
If IsImage(IMG_canvas)
If w = Canvas_W And h = Canvas_H
ProcedureReturn #False
EndIf
EndIf
If w < 1 : w = 1 : EndIf
If h < 1 : h = 1 : EndIf
If w > 100 : w = 100 : EndIf
If h > 100 : h = 100 : EndIf
SetGadgetText(GD_String_2, Str(w))
SetGadgetText(GD_String_3, Str(h))
;}
ratio = w / h
Canvas_W = w
Canvas_H = h
If ratio > 1
Canvas_0_w = 220
Canvas_0_h = 220 / ratio
Else
Canvas_0_h = 220
Canvas_0_w = 220 * ratio
EndIf
Canvas_RATIO = Canvas_0_w / w
ResizeGadget(GD_Canvas_0, 340 + 110 - Canvas_0_w / 2, 50 + 110 - Canvas_0_h / 2, Canvas_0_w, Canvas_0_h)
If NePasToucherImage = #False
If IsImage(IMG_canvas)
FreeImage(IMG_canvas)
EndIf
IMG_canvas = CreateImage(#PB_Any, w, h)
StartDrawing(ImageOutput(IMG_canvas))
Box(0, 0, w, h, #White)
StopDrawing()
StartDrawing(CanvasOutput(GD_Canvas_0))
Box(0, 0, Canvas_0_w, Canvas_0_h, #White)
StopDrawing()
EndIf
EndProcedure
Procedure MiseAJour_ImageCanvas(image)
Protected x, y
If IsImage(image) = 0
ProcedureReturn #False
EndIf
SetGadgetText(GD_String_2, Str(ImageWidth(IMG_canvas)))
SetGadgetText(GD_String_3, Str(ImageHeight(IMG_canvas)))
MiseAJour_TailleCanvas(#True)
Protected Dim tableau(ImageWidth(image) - 1, ImageHeight(image) - 1)
StartDrawing(ImageOutput(image))
For x = 0 To ImageWidth(image) - 1
For y = 0 To ImageHeight(image) - 1
tableau(x, y) = Point(x, y)
Next
Next
StopDrawing()
StartDrawing(CanvasOutput(GD_Canvas_0))
For x = 0 To ImageWidth(image) - 1
For y = 0 To ImageHeight(image) - 1
Box(x * Canvas_RATIO, y * Canvas_RATIO, Round(Canvas_RATIO, #PB_Round_Up), Round(Canvas_RATIO, #PB_Round_Up), tableau(x, y))
Next
Next
StopDrawing()
EndProcedure
Procedure MiseAJour_DessinCanvas()
Protected mouse.POINT, color
If IsImage(IMG_canvas) = 0
MiseAJour_TailleCanvas()
EndIf
If GetGadgetAttribute(GD_Canvas_0, #PB_Canvas_Buttons) & #PB_Canvas_LeftButton = #PB_Canvas_LeftButton
color = 0
ElseIf GetGadgetAttribute(GD_Canvas_0, #PB_Canvas_Buttons) & #PB_Canvas_RightButton = #PB_Canvas_RightButton
color = #White
Else
ProcedureReturn #False
EndIf
mouse\x = GetGadgetAttribute(GD_Canvas_0, #PB_Canvas_MouseX)
mouse\y = GetGadgetAttribute(GD_Canvas_0, #PB_Canvas_MouseY)
; If mouse\x < 0 : mouse\x = 0 : EndIf
; If mouse\y < 0 : mouse\y = 0 : EndIf
; If mouse\x > GadgetWidth(GD_Canvas_0) : mouse\x = GadgetWidth(GD_Canvas_0) : EndIf
; If mouse\y > GadgetHeight(GD_Canvas_0) : mouse\y = GadgetHeight(GD_Canvas_0) : EndIf
mouse\x = Round(mouse\x / Canvas_RATIO, #PB_Round_Down)
mouse\y = Round(mouse\y / Canvas_RATIO, #PB_Round_Down)
If mouse\x >= ImageWidth(IMG_canvas) : mouse\x = ImageWidth(IMG_canvas) - 1: EndIf
If mouse\y >= ImageHeight(IMG_canvas) : mouse\y = ImageHeight(IMG_canvas) - 1 : EndIf
If StartDrawing(ImageOutput(IMG_canvas))
Plot(mouse\x, mouse\y, color)
StopDrawing()
EndIf
If StartDrawing(CanvasOutput(GD_Canvas_0))
Box(mouse\x * Canvas_RATIO, mouse\y * Canvas_RATIO, Round(Canvas_RATIO, #PB_Round_Up), Round(Canvas_RATIO, #PB_Round_Up), color)
; DrawImage(ImageID(IMG_canvas), 0, 0)
StopDrawing()
EndIf
ProcedureReturn #True
EndProcedure
Procedure MiseAJour_Image(Gadget, image, pos_x, pos_y, largeur_cote)
Protected x, y, image_old, ratio.d, Image_w, Image_h, RATIO_petit_grand.d
If IsImage(image) = 0
ProcedureReturn #False
EndIf
image_old = GetGadgetData(Gadget)
If IsImage(image_old)
FreeImage(image_old)
EndIf
Protected Dim tableau(ImageWidth(image) - 1, ImageHeight(image) - 1)
StartDrawing(ImageOutput(image))
For x = 0 To ImageWidth(image) - 1
For y = 0 To ImageHeight(image) - 1
tableau(x, y) = Point(x, y)
Next
Next
StopDrawing()
ratio = ImageWidth(image) / ImageHeight(image)
If ratio > 1
Image_w = largeur_cote
Image_h = largeur_cote / ratio
Else
Image_h = largeur_cote
Image_w = largeur_cote * ratio
EndIf
RATIO_petit_grand = Image_w / ImageWidth(image)
image_old = CreateImage(#PB_Any, Image_w, Image_h)
StartDrawing(ImageOutput(image_old))
For x = 0 To ImageWidth(image) - 1
For y = 0 To ImageHeight(image) - 1
Box(x * RATIO_petit_grand, y * RATIO_petit_grand, Round(RATIO_petit_grand, #PB_Round_Up), Round(RATIO_petit_grand, #PB_Round_Up), tableau(x, y))
Next
Next
StopDrawing()
SetGadgetData(Gadget, image_old)
SetGadgetState(Gadget, ImageID(image_old))
ResizeGadget(Gadget, pos_x + (largeur_cote - image_w) / 2, pos_y + (largeur_cote - image_h) / 2, #PB_Ignore, #PB_Ignore)
EndProcedure
DisableExplicit
;{ Fenêtre
Procedure OpenWD_Window_0()
WD_Window_0 = OpenWindow(#PB_Any, 0, 0, 690, 550, "Memoire Associative", #PB_Window_ScreenCentered | #PB_Window_SystemMenu)
GD_ListIcon_0 = ListIconGadget(#PB_Any, 10, 10, 110, 270, "Images", 50, #PB_ListIcon_AlwaysShowSelection)
GD_Frame3D_0 = Frame3DGadget(#PB_Any, 130, 0, 190, 140, "")
GD_Text_0 = TextGadget(#PB_Any, 140, 20, 90, 20, "Image soumise :")
GD_Image_0 = ImageGadget(#PB_Any, 260, 20, 50, 50, 0, #PB_Image_Border)
GD_Text_1 = TextGadget(#PB_Any, 140, 80, 90, 20, "Résultat :")
GD_Image_1 = ImageGadget(#PB_Any, 260, 80, 50, 50, 0, #PB_Image_Border)
GD_Frame3D_1 = Frame3DGadget(#PB_Any, 130, 140, 190, 140, "")
GD_Text_2 = TextGadget(#PB_Any, 140, 150, 170, 20, "Taille de l'info de sortie :")
GD_Text_3 = TextGadget(#PB_Any, 140, 173, 50, 20, "W x H =")
GD_String_0 = StringGadget(#PB_Any, 200, 170, 30, 20, "5", #PB_String_Numeric)
GD_Text_4 = TextGadget(#PB_Any, 240, 173, 10, 20, "x")
GD_String_1 = StringGadget(#PB_Any, 260, 170, 30, 20, "7", #PB_String_Numeric)
GD_Text_8 = TextGadget(#PB_Any, 140, 198, 50, 20, "Cycle Out")
GD_String_5 = StringGadget(#PB_Any, 200, 195, 30, 20, "20", #PB_String_Numeric)
GD_Text_9 = TextGadget(#PB_Any, 240, 198, 10, 20, "µ")
GD_String_6 = StringGadget(#PB_Any, 260, 195, 30, 20, "0.2")
GD_Button_0 = ButtonGadget(#PB_Any, 140, 250, 170, 20, "Effectuer l'apprentissage")
GD_Button_1 = ButtonGadget(#PB_Any, 140, 220, 170, 20, "Redéfinir les neurones")
GD_Frame3D_2 = Frame3DGadget(#PB_Any, 330, 0, 350, 280, "")
GD_Text_7 = TextGadget(#PB_Any, 340, 20, 40, 20, "Nom :")
GD_String_4 = StringGadget(#PB_Any, 390, 20, 50, 20, "")
GD_Canvas_0 = CanvasGadget(#PB_Any, 340, 50, 220, 220, #PB_Canvas_ClipMouse)
GD_Text_5 = TextGadget(#PB_Any, 520, 20, 50, 20, "W x H =")
GD_String_2 = StringGadget(#PB_Any, 580, 20, 30, 20, "5", #PB_String_Numeric)
GD_Text_6 = TextGadget(#PB_Any, 620, 20, 10, 20, "x")
GD_String_3 = StringGadget(#PB_Any, 640, 20, 30, 20, "7", #PB_String_Numeric)
GD_Button_2 = ButtonGadget(#PB_Any, 570, 50, 100, 20, "Soumettre")
GD_Button_3 = ButtonGadget(#PB_Any, 570, 80, 100, 40, "Enregistrer une nouvelle Image", #PB_Button_MultiLine)
GD_Button_4 = ButtonGadget(#PB_Any, 570, 130, 100, 50, "Enregistrer sur l'image sélectionnée", #PB_Button_MultiLine)
GD_Button_5 = ButtonGadget(#PB_Any, 570, 190, 100, 40, "Supprimer l'image sélectionnée", #PB_Button_MultiLine)
GD_Button_6 = ButtonGadget(#PB_Any, 570, 240, 100, 30, "Chargement auto", #PB_Button_MultiLine | #PB_Button_Toggle)
GD_Editor_0 = EditorGadget(#PB_Any, 10, 290, 670, WindowHeight(WD_Window_0) - 300)
AddKeyboardShortcut(WD_Window_0, #PB_Shortcut_Escape, 0)
AddKeyboardShortcut(WD_Window_0, #PB_Shortcut_Return, 1)
SetGadgetAttribute(GD_ListIcon_0, #PB_ListIcon_DisplayMode, #PB_ListIcon_DisplayMode)
SetGadgetState(GD_Button_6, #True)
MiseAJour_TailleCanvas()
EndProcedure
OpenWD_Window_0()
;}
;}
;{ chargement de la base de donnée des images
ChargementImageDATA("Image_DATA.img")
Nb = Val(GetGadgetText(GD_String_0)) * Val(GetGadgetText(GD_String_1))
*Memoire.MemoireAssociative = CreationMemoireAssociative(Nb, Nb)
;}
Repeat
event = WaitWindowEvent()
;{ gestion évènements
Select event
Case #PB_Event_Menu
;{ menus
Select EventMenu()
Case 0 ; Key_escape
event = #PB_Event_CloseWindow
Case 1 ; Key_Return
If GetActiveGadget() = GD_String_2 Or GetActiveGadget() = GD_String_3
MiseAJour_TailleCanvas()
EndIf
EndSelect
;}
;{ Gadgets
Case #PB_Event_Gadget
Select EventGadget()
Case GD_Button_3
;{ enregistrer une nouvelle image
If IsImage(IMG_canvas)
AddGadgetItem(GD_ListIcon_0, -1, GetGadgetText(GD_String_4), ImageID(IMG_canvas))
SetGadgetItemData(GD_ListIcon_0, CountGadgetItems(GD_ListIcon_0) - 1, IMG_canvas)
IMG_canvas = 0
MiseAJour_TailleCanvas()
EndIf
;}
Case GD_Button_4
;{ enregistrer sur l'image sélectionnée, l'ancienne image est perdue
elem_selc = GetGadgetState(GD_ListIcon_0)
If elem_selc <> -1 And IsImage(IMG_canvas)
IMG_suppr = GetGadgetItemData(GD_ListIcon_0, elem_selc)
If IsImage(IMG_suppr)
FreeImage(IMG_suppr)
EndIf
SetGadgetItemText(GD_ListIcon_0, elem_selc, GetGadgetText(GD_ListIcon_0))
SetGadgetItemImage(GD_ListIcon_0, elem_selc, ImageID(IMG_canvas))
SetGadgetItemData(GD_ListIcon_0, elem_selc, IMG_canvas)
IMG_canvas = 0
MiseAJour_TailleCanvas()
EndIf
;}
Case GD_Button_5
;{ supprimer l'image sélectionnée
elem_selc = GetGadgetState(GD_ListIcon_0)
If elem_selc <> -1
IMG_suppr = GetGadgetItemData(GD_ListIcon_0, elem_selc)
If IsImage(img_suppr)
FreeImage(IMG_suppr)
EndIf
RemoveGadgetItem(GD_ListIcon_0, elem_selc)
EndIf
;}
Case GD_ListIcon_0
;{ Chargement d'une image par clic sur la ListIcon
If GetGadgetState(GD_Button_6) = #True
; chargement dans le panneau de modification
elem_selc = GetGadgetState(GD_ListIcon_0)
If elem_selc <> -1
If IsImage(IMG_canvas)
FreeImage(IMG_canvas)
EndIf
IMG_canvas = GetGadgetItemData(GD_ListIcon_0, elem_selc)
IMG_canvas = CopyImage(IMG_canvas, #PB_Any)
SetGadgetText(GD_String_4, GetGadgetItemText(GD_ListIcon_0, elem_selc))
; dessin de l'image dans le canvas
MiseAJour_ImageCanvas(IMG_canvas)
EndIf
EndIf
;}
Case GD_String_2, GD_String_3
;{ Modification de la taille du canvas
If EventType() = #PB_EventType_LostFocus
MiseAJour_TailleCanvas()
EndIf
;}
Case GD_Canvas_0
;{ dessin sur le canvas
MiseAJour_DessinCanvas()
;}
Case GD_Button_1
;{ Redéfinir les neurones
If *Memoire
FreeMemoireAssociative(*Memoire)
EndIf
Nb = Val(GetGadgetText(GD_String_0)) * Val(GetGadgetText(GD_String_1))
*Memoire = CreationMemoireAssociative(Nb, Nb)
;}
Case GD_Button_0
;{ Effectuer l'apprentissage
If CountGadgetItems(GD_ListIcon_0) = 0
MessageRequester("Attention", "Base d'Image vide")
Else
IMG_premierItem = GetGadgetItemData(GD_ListIcon_0, 0)
If IsImage(IMG_premierItem)
; création de la base d'apprentissage
*Base.BaseApprentissage = CreationBaseApprentissage(ImageWidth(IMG_premierItem) * ImageHeight(IMG_premierItem))
Message("Base d'apprentissage créée")
; ajout des exemples, ils doivent avoir la même dimension que la première image, sinon, ils ne seront pas ajoutés
image_ajoutee = 0
For i = 0 To CountGadgetItems(GD_ListIcon_0) - 1
IMG_select = GetGadgetItemData(GD_ListIcon_0, i)
If IsImage(IMG_select) And ImageWidth(IMG_premierItem) = ImageWidth(IMG_select) And ImageHeight(IMG_premierItem) = ImageHeight(IMG_select) And Ajout_Exemple_Apprentissage(*Base, IMG_select)
image_ajoutee + 1
EndIf
Next
Message(Str(image_ajoutee) + " images de " + Str(ImageWidth(IMG_premierItem)) + " x "+ Str(ImageHeight(IMG_premierItem)) + " ajoutées à la Base d'apprentissage")
; Lancement de l'apprentissage :
CycleOut = Val(GetGadgetText(GD_String_5))
Mu.d = ValD(GetGadgetText(GD_String_6))
If Mu = 0 : Mu = 0.2 : SetGadgetText(GD_String_6, StrD(Mu)) : EndIf
res = Apprentissage_MemoireAssociative(*Memoire, *Base, Mu, CycleOut)
Select res
Case -1
Message("Apprentissage Echoué - Non correspondance entre le nombre d'entrée de la base et de la mémoire")
Case 0
Message("Apprentissage Réussi")
Default
Message("Apprentissage Impossible - " + Str(res) + " Cycles")
EndSelect
FreeBaseApprentissage(*Base)
Message("Base d'apprentissage libérée")
EndIf
EndIf
;}
Case GD_Button_2
;{ Soumettre une image
If IsImage(IMG_resultat)
FreeImage(IMG_resultat)
EndIf
If IsImage(IMG_canvas)
Message("Nouvelle image soumise à la mémoire")
MiseAJour_Image(GD_Image_0, IMG_canvas, 260, 20, 50)
IMG_resultat = CalculReponse(*Memoire, IMG_canvas)
If IsImage(IMG_resultat)
MiseAJour_Image(GD_Image_1, IMG_resultat, 260, 80, 50)
EndIf
EndIf
;}
EndSelect
;}
EndSelect
;}
Until event = #PB_Event_CloseWindow
;{ sauvegarde des données images
SauvegardeImageDATA("Image_DATA.img")
;}
End
; Début du test
;{ Test 1
; ; création de la base d'exemple
; *Base.BaseApprentissage = CreationBaseApprentissage(4)
;
; ; ajout des exemples dans la base :
; Ajout_Exemple_Apprentissage(*Base, "1,-1,1,-1,1")
; Ajout_Exemple_Apprentissage(*Base, "1,1,1,1,1")
; Ajout_Exemple_Apprentissage(*Base, "1,1,1,-1,-1")
; Ajout_Exemple_Apprentissage(*Base, "1,-1,-1,1,-1")
;
;
; ; création du neurone
; *Neurone.Neurone = CreationNeurone(4, 0.1, #False)
;
; ; Apprentissage
; If Apprentissage(*Neurone, *Base, 0.1) = #False
; Debug ""
; Debug "Aucune solution n'a été trouvée."
; EndIf
;
;
; ; Affichage des résultats (poids) :
; Debug ""
; Debug "Résultats"
; ForEach *Neurone\PoidsEntree()
; Debug "w" + Str(ListIndex(*Neurone\PoidsEntree())+1) + " = " + *Neurone\PoidsEntree()
; Next
; Debug "Seuil = " + *Neurone\Seuil
;}
_________________________________________________
Mon site : CeriseCode (Attention Chantier perpétuel
)
Mon site : CeriseCode (Attention Chantier perpétuel

- Kwai chang caine
- Messages : 6989
- Inscription : sam. 23/sept./2006 18:32
- Localisation : Isere
Re: Pour les matheux ..se contruire un mini OCR
Tout d'abord merci à tous de votre réponse 
@GRom et MindPhaser
Sincèrement, je voyais pas ça si compliqué, étant donné que je connais la police qui va être utilisée, que c'est toujours la même, juste la hauteur varie selon la page.
Parce que le coups du perfectron
Autant vous dire que ça dépasse mes capacités et surement celle de 5 générations de ma descendance que je n'aurais jamais
Et puis mon code a pas besoin d'apprendre, il a besoin de savoir
Une fois qu'on lui aura expliqué correctement ce qu'est un A, ce sera toujours le même.
En tout cas merci, GRom, encore un lien qui me prouve que j'aurais du aller à l’école plus longtemps, et surtout ne pas avoir passé mon temps à me retourner et de ce fait visiter les 4 angles toute l'année
C'est ce genre de page qui me déprime, une fois j'avais eu la géniale idée de créer un cryptage, et comme le résultat était trop long, je me suis lancé a aller sur les forums de matheux, pour leur demander comment on pourrait réduire ce dernier.
Les gens ont été gentils, mais plus ils m'expliquait, plus je visitais ces sites, plus lé genèse de l'humanité que je croyais sommeiller au plus profond de moi resurgissait, pour ne plus générer qu'un seul son qui fut emmis de ma bouche beante : "Honk honk"
C'est à ce moment que l'on s'apperçoit de la monstruasité du savoir de l'humanité
On se retrouve a la marternelle devant des sites comme ceux-ci, que dis je la maternelle....à la creche
Et c'est ça dans tous les domaines, le français, les math, chaque type de technologie (Des milliers), le médical, etc ..
Quoi qu'il en soit merci encore de ta reponse Grom et du lien Mindphaser
@Frenchy pilou
Merci pour le lien, mais j'ai déjà un mal fou à lire et écrire l'anglais, mais je comprend pas le canard ...ce mec a le débit d'une mitrailleuse et l'articulation d'un anus de none
Ce qui est sur, c'est que j'avais appris qu'un malin avait pensé à créer un site de cul par exemple, ou un site de warez en proposant des trucs de "guedin" à la portée d'un clic
Style la photo de mylene farmer nue, ou johnny hallyday en pleine action, ou des maxis logiciels gratuits...etc
Evidemment plein de bourrins naifs cliquaient sur les liens et se retrouvaient devant un captcha qu'ils decryptaient manuellement et envoyaient au site qui en retour évidemment ne donnait pas les choses promises.
L’intérêt ?? c'est que tellement de personnes s'occupaient donc de décrypter gratos les fameux captcha en direct, il suffisait d'attendre un peu pour qu'un pigeon se fasse prendre et decrypte a la place du robot le captcha et renvoi la reponse au robot pour qu'a son tour il clique sur un lien l'ammenant devant un autre captcha qu'il envoyait a nouveau a ce faux sites en attendant le prochain pigeon
En attendant l'idée était géniale...je sais pas si c'est celle ci ??
Pour l'OCR, je ne peux pas utiliser internet, mais quoi qu'il en soit merci pour le lien ça peu être utile
J'ai aussi testé des OCR open source comme tesseract, mais les resultats sont pas tres probants
@Graph100
Merci pour ton code
Et ben, je vais essayer de le comprendre..mais je pensais pas qu'il faille que je refasse "la creation" en partant de l'atome pour decoder 62 lettres et 10 chiffres.
En tout cas bravo, tu fais de ces trucs de dingues dans tes cours
Encore merci à vous tous de m'avoir donné votre avis, on peut pas dire que ce soit super encourageant, mais ça aide quand même

@GRom et MindPhaser
Sincèrement, je voyais pas ça si compliqué, étant donné que je connais la police qui va être utilisée, que c'est toujours la même, juste la hauteur varie selon la page.
Parce que le coups du perfectron

Autant vous dire que ça dépasse mes capacités et surement celle de 5 générations de ma descendance que je n'aurais jamais

Et puis mon code a pas besoin d'apprendre, il a besoin de savoir

Une fois qu'on lui aura expliqué correctement ce qu'est un A, ce sera toujours le même.
En tout cas merci, GRom, encore un lien qui me prouve que j'aurais du aller à l’école plus longtemps, et surtout ne pas avoir passé mon temps à me retourner et de ce fait visiter les 4 angles toute l'année

C'est ce genre de page qui me déprime, une fois j'avais eu la géniale idée de créer un cryptage, et comme le résultat était trop long, je me suis lancé a aller sur les forums de matheux, pour leur demander comment on pourrait réduire ce dernier.
Les gens ont été gentils, mais plus ils m'expliquait, plus je visitais ces sites, plus lé genèse de l'humanité que je croyais sommeiller au plus profond de moi resurgissait, pour ne plus générer qu'un seul son qui fut emmis de ma bouche beante : "Honk honk"

C'est à ce moment que l'on s'apperçoit de la monstruasité du savoir de l'humanité

On se retrouve a la marternelle devant des sites comme ceux-ci, que dis je la maternelle....à la creche

Et c'est ça dans tous les domaines, le français, les math, chaque type de technologie (Des milliers), le médical, etc ..
Quoi qu'il en soit merci encore de ta reponse Grom et du lien Mindphaser

@Frenchy pilou
Merci pour le lien, mais j'ai déjà un mal fou à lire et écrire l'anglais, mais je comprend pas le canard ...ce mec a le débit d'une mitrailleuse et l'articulation d'un anus de none

Ce qui est sur, c'est que j'avais appris qu'un malin avait pensé à créer un site de cul par exemple, ou un site de warez en proposant des trucs de "guedin" à la portée d'un clic
Style la photo de mylene farmer nue, ou johnny hallyday en pleine action, ou des maxis logiciels gratuits...etc
Evidemment plein de bourrins naifs cliquaient sur les liens et se retrouvaient devant un captcha qu'ils decryptaient manuellement et envoyaient au site qui en retour évidemment ne donnait pas les choses promises.
L’intérêt ?? c'est que tellement de personnes s'occupaient donc de décrypter gratos les fameux captcha en direct, il suffisait d'attendre un peu pour qu'un pigeon se fasse prendre et decrypte a la place du robot le captcha et renvoi la reponse au robot pour qu'a son tour il clique sur un lien l'ammenant devant un autre captcha qu'il envoyait a nouveau a ce faux sites en attendant le prochain pigeon

En attendant l'idée était géniale...je sais pas si c'est celle ci ??
Pour l'OCR, je ne peux pas utiliser internet, mais quoi qu'il en soit merci pour le lien ça peu être utile

J'ai aussi testé des OCR open source comme tesseract, mais les resultats sont pas tres probants

@Graph100
Merci pour ton code

Et ben, je vais essayer de le comprendre..mais je pensais pas qu'il faille que je refasse "la creation" en partant de l'atome pour decoder 62 lettres et 10 chiffres.
En tout cas bravo, tu fais de ces trucs de dingues dans tes cours

Encore merci à vous tous de m'avoir donné votre avis, on peut pas dire que ce soit super encourageant, mais ça aide quand même

Re: Pour les matheux ..se contruire un mini OCR
si effectivement la police reste la meme , pas besoin d'usine a gaz !
j'avais balancé sur le forum , un prg qui etait capable de différencier 2 images
ben la le principe est le meme ,
le seul probleme va etre de caler chaque lettre de sorte qu'elle soient toute positionné
de la meme façon par rapport a un repère , comme le bas-gauche ou le haut gauche de l'image contenant chaque lettre
a analyser ... ya un decoupage a faire ... une image= le caractère a analyser ..
une fois que tu as resolu ce probleme ,
tu fait un petit algo qui va regarder certains pixel de l'image contenant la lettre
tu retiens leur couleur (l'ideal serai d'avoir juste le noir et le blanc il existe des algo sur le forum pour ça)
tu as donc une "matrice" de pixel( de position de pixel noirs) ( pas besoin d'en avoir beaucoup , je pense que 10 serai bien)
il te suffit de faire "Apprendre" a ton programe que lorsque le pixel (20,10) et le pixel(30,30) .....etc.. sont tous noir
tu recherche la correspondance dans tes matrices, si ça correspond au information de ta matrice "_A" , donc il s'agit d'un "A" (par exemple)
une fois ta base de donnée de position de pixel noir est faite (il y aura donc environs 130 "Matrices" de 10 positions de pixels
130 car je compte les signes comme la virgule etc ...
il te suffira donc de comparer l'image a analyser , avec ta base de donnée et de sortir le caractère correspondant
je sais pas si je suis clair , mais j'me comprends , c'est deja pas mal
une matrice peut etre encodé sur une seule ligne sous la forme binaire des points noir , ça evite de retenir une coordonées
exemple le Signe "L" correspondrai a
"100000"
"100000"
"100000"
"11111"
ce qui fait "10000010000010000011111" ... bon il ya surement d'autres façon d'encoder l'info
donc si dans ton image la sequence binaire correspond a "10000010000010000011111" ou a une grosse partie de cette info comme "1xxx00100xxx10000011xx1"
ben c'est que c'est un "L" ou que ça y ressemble vachement
j'avais balancé sur le forum , un prg qui etait capable de différencier 2 images
ben la le principe est le meme ,
le seul probleme va etre de caler chaque lettre de sorte qu'elle soient toute positionné
de la meme façon par rapport a un repère , comme le bas-gauche ou le haut gauche de l'image contenant chaque lettre
a analyser ... ya un decoupage a faire ... une image= le caractère a analyser ..
une fois que tu as resolu ce probleme ,
tu fait un petit algo qui va regarder certains pixel de l'image contenant la lettre
tu retiens leur couleur (l'ideal serai d'avoir juste le noir et le blanc il existe des algo sur le forum pour ça)
tu as donc une "matrice" de pixel( de position de pixel noirs) ( pas besoin d'en avoir beaucoup , je pense que 10 serai bien)
il te suffit de faire "Apprendre" a ton programe que lorsque le pixel (20,10) et le pixel(30,30) .....etc.. sont tous noir
tu recherche la correspondance dans tes matrices, si ça correspond au information de ta matrice "_A" , donc il s'agit d'un "A" (par exemple)
une fois ta base de donnée de position de pixel noir est faite (il y aura donc environs 130 "Matrices" de 10 positions de pixels
130 car je compte les signes comme la virgule etc ...
il te suffira donc de comparer l'image a analyser , avec ta base de donnée et de sortir le caractère correspondant
je sais pas si je suis clair , mais j'me comprends , c'est deja pas mal

une matrice peut etre encodé sur une seule ligne sous la forme binaire des points noir , ça evite de retenir une coordonées
exemple le Signe "L" correspondrai a
"100000"
"100000"
"100000"
"11111"
ce qui fait "10000010000010000011111" ... bon il ya surement d'autres façon d'encoder l'info

donc si dans ton image la sequence binaire correspond a "10000010000010000011111" ou a une grosse partie de cette info comme "1xxx00100xxx10000011xx1"
ben c'est que c'est un "L" ou que ça y ressemble vachement

Re: Pour les matheux ..se contruire un mini OCR
pas bête ton tableau de boolean , tu pourrais même en comparant les tableaux entre eux fixé un % de marge d'erreur pour donner de la souplesse au système.
Re: Pour les matheux ..se contruire un mini OCR
oui , tout a fait 
pour le fait de repérer quelques pixel dans une image pour l'identifier , ça marche deja tres bien a partir
de 3 pixels
mais pour une fonte c'est plus precis , pour ne pas confondre un "V" avec un "U" ils faut augmenter
la matrice de reference
revoici mon code qui compare 2 images, et qui est capable de dire si elle sont pareil ou pas ...
pour une lettre c'est la meme chose, on la compare a une reference (binaire..ou quelques pixel clef sont important) au lieu de la comparer a une autre lettre ..
ici la tolerance est lié au nombres de pixels vérifié ..
le principe est là

pour le fait de repérer quelques pixel dans une image pour l'identifier , ça marche deja tres bien a partir
de 3 pixels

mais pour une fonte c'est plus precis , pour ne pas confondre un "V" avec un "U" ils faut augmenter
la matrice de reference

revoici mon code qui compare 2 images, et qui est capable de dire si elle sont pareil ou pas ...
pour une lettre c'est la meme chose, on la compare a une reference (binaire..ou quelques pixel clef sont important) au lieu de la comparer a une autre lettre ..
ici la tolerance est lié au nombres de pixels vérifié ..
le principe est là

Code : Tout sélectionner
;{- Enumerations / DataSections
;{ Windows
; Code Par Dobro
; en Purebasic 5.11
Enumeration
#Window
EndEnumeration
;}
;{ Gadgets
Enumeration
#titre
#info
#Button_image1
#Button_image2
#Button_compare
#input
#image1
#image2
EndEnumeration
global path$=""
UseJPEGImageDecoder()
UsePNGImageDecoder()
UseTGAImageDecoder()
;
Declare OpenWindow_Window()
Declare compare(im1,im2,po)
Declare taux(couleur)
;to predict the test on the color component of the point and not on the exact color .... (taux de rouge, vert,bleu)
;}
;{ Fonts
Enumeration
#Font_titre
EndEnumeration
;}
Define.l Event, EventWindow, EventGadget, EventType, EventMenu
;}
Procedure OpenWindow_Window()
If OpenWindow(#Window, 554, 111, 354, 191, "By Dobro", #PB_Window_SystemMenu|#PB_Window_MinimizeGadget|#PB_Window_TitleBar|#PB_Window_SizeGadget)
TextGadget(#titre, 10, 10, 375, 35, "Comparateur d'image", #PB_Text_Center)
ButtonGadget(#Button_image1, 30, 90, 115, 35, "Load Picture 1")
ButtonGadget(#Button_image2, 30, 135, 115, 35, "Load Picture 2")
ButtonGadget(#Button_compare, 230, 135, 115, 35, "compare !")
TextGadget(#info, 10, 60, 200, 35, "number of points to be compared", #PB_Text_Center) ; >3 !!
StringGadget(#input, 200, 60, 50, 35, "3" ,#PB_String_Numeric )
; Gadget Fonts
SetGadgetFont(#titre, LoadFont(#Font_titre, "Comic Sans MS", 16, #PB_Font_Bold|#PB_Font_HighQuality))
EndIf
EndProcedure
OpenWindow_Window()
;{- Event loop
Repeat
Event = WaitWindowEvent()
Select Event
; ///////////////////
Case #PB_Event_Gadget
EventGadget = EventGadget()
EventType = EventType()
select EventGadget
case #titre
case #Button_image1
if path$=""
path$="c:\"
endif
file$=OpenFileRequester("Load Picture 1",path$,"*.*",0)
if loadimage(#image1,file$)<>0
Else
MessageRequester("info","Picture not loaded",#PB_MessageRequester_Ok)
endif
case #Button_image2
if path$=""
path$="c:\"
endif
file$=OpenFileRequester("Load Picture 2",path$,"*.*",0)
if loadimage(#image2,file$) <>0
else
MessageRequester("info","Picture not loaded",#PB_MessageRequester_Ok)
endif
case #Button_compare
po=val(GetGadgetText(#input))
if compare(#image1,#image2,po)=#true
MessageRequester("info","This is certainly the same image",#PB_MessageRequester_Ok)
Else
MessageRequester("info","This is not the same image",#PB_MessageRequester_Ok)
endif
Endselect
; ////////////////////////
Case #PB_Event_CloseWindow
EventWindow = EventWindow()
If EventWindow = #Window
CloseWindow(#Window)
Break
EndIf
EndSelect
Forever
; **************************** Zone des procedures **********************************²
procedure compare(im1,im2,po)
; By Dobro
; im1 = numero de l'image 1
; im2 = numero de l'image 2
; po = nombre de points de comparaison , plus il y en a plus c'est long, mais plus c'est bon LOL
structure coordo
x.l ; coordonné x du point
y.l ; coordonné y du point
couleur.l ; la couleur du point
endstructure
dim coordo.coordo(po) ; et met leur coordonnés dans la structure ainsi que leur couleur !
if po<=3 :po=3:endif ; petite securité on verifie au moins 1 point
if IsImage(#image1)<>0
Else
MessageRequester("Erreur","the images were not loaded", #PB_MessageRequester_Ok )
ProcedureReturn #false
endif
if IsImage(#image2)<>0
Else
MessageRequester("Erreur","the images were not loaded", #PB_MessageRequester_Ok )
ProcedureReturn #false
endif
x_im1=ImageWidth(#image1)
y_im1=ImageHeight(#image1)
x_im2=ImageWidth(#image2)
y_im2=ImageHeight(#image2)
if x_im1<=x_im2:x_de=x_im1:else: x_de=x_m2-1:endif ; on va recuperer la resolution la plus petite
if y_im1<=y_im2:y_de=y_im1:else: y_de=y_m2-1:endif; entre les 2 images
if po> (x_de * y_de) : po=(x_de * y_de)/4:endif ; petite securité au cas ou po serai superieur au nombre de points de l'image
; ********* tire les points au dé ************
StartDrawing(ImageOutput(#image1))
for i=1 to po ; pour tout les points
coordo(i)\x.l=random(x_de-1) ; on recup la coordonée x dans l'image 1
coordo(i)\y.l=random(y_de-1) ; on recup la coordonée y dans l'image 1
coordo(i)\couleur.l=taux(point(coordo(i)\x.l,coordo(i)\y.l) ) ; on recup la couleur dans l'image 1
next i
StopDrawing()
; ****************************************
; on va comparer si les points sont pareil entre les 2 images
StartDrawing(ImageOutput(#image2))
for i=1 to po ; pour tout les points
coul=taux(point(coordo(i)\x.l,coordo(i)\y.l) )
if coul <> coordo(i)\couleur.l ; le point est different .. c'est pas le meme image
diff=diff+1
endif
next i
StopDrawing()
if diff<(po/3) ; le seuil de difference est inferieur au tier des points (moins du tier des points sont different)
ProcedureReturn #true ; c'est certainement la meme image ( tout depend du nombre de point testé )
Else
ProcedureReturn #false ; trop de difference ! c'est pas la meme image
endif
endprocedure
procedure taux(couleur)
taux_rouge=int((red(couleur)/255)*100)
taux_vert=int((green(couleur)/255)*100)
taux_bleu=int((blue(couleur)/255)*100)
total=int(taux_rouge+taux_vert+taux_bleu)/3
ProcedureReturn total
endprocedure
; **********************************************************************************
;}
; EPB
-
- Messages : 2194
- Inscription : jeu. 27/janv./2005 19:07
Re: Pour les matheux ..se contruire un mini OCR
Pour plus de précision (et en françaisEn attendant l'idée était géniale...je sais pas si c'est celle ci ??

http://fr.wikipedia.org/wiki/CAPTCHA
et évidemment celle-ci qui est sacrément futée! (toujours en français

http://fr.wikipedia.org/wiki/ReCAPTCHA
- Kwai chang caine
- Messages : 6989
- Inscription : sam. 23/sept./2006 18:32
- Localisation : Isere
Re: Pour les matheux ..se contruire un mini OCR
@DOBRO
Alors la l'idée de mettre tout en une seule phrase c'est fort, j'y avais pas pensé
Moi j'avais eu la même idée en utilisant un tableau, parce que bettement un tableau est "carré" donc ressemble à une matrice, mais c'est vrais que y mettre sur une ligne, c'est un peu moins lisible pour l'humain, mais surement mieux pour la machine
Pour ce qui est de la couleur, j'avais aussi pensé à la retirer, car mes essais de la semaine derniere avaient été sur des images enregistrées avec un programme SnapShot en 1 bit, en fait je savais pas ce que ça voulait dire, mais j'ai decouvert a force d'essais que moins on mettait de bit et plus le rechercheur d'image l'une dans l'autre s'en sortait.
apres j'ai vu que 1 bit ça donnait noir et blanc (Normal deux etats, mais j'ai compris qu'apres
)
En plus j'suis obligé, parce que ces bourrins pour corser le tout ont mis une ligne sur deux de fond de chaque couleur, et aussi une autre couleur de fond au survol de la souris
Donc pour la couleur, je devrais avoir trouvé le truc, en plus, les dieux sont un peu avec moi, car en plus de votre aide, je viens de voir un post qui convertit les images en 1 bit (On aurait dit qu'il m'avait entendu dans mes nuits
)
J'ai aussi remarqué que le travail en BMP est préférable, les programmes retrouvent mieux les images dans les BMP que les autres formats compressés.
Pour le callage, tu as raison, j'ai pas encore commencé la découpe des bandes mais je devrait y arriver, il suffit de scanner les pixels avec un trait comme sur un scanner en partant de la gauche par exemple, et des que l'on trouve un pixel sur la ligne qui n'est pas de la couleur du fond a priori ce devrait être le début de la lettre, si y'a pas des merdouilles autour, car j'ai aussi découverts que quand on grossi mortel l'image autour y'a des pixels qui sont ni couleur du fond, ni couleur du caractère, mais comme le dit GRom je pourrais peut être utiliser une marge d'erreur, enfin si j'y arrive
Reste le problème de la taille, car même police, mais taille différente, donc comme tu me le confirme, le fait de créer une matrice devrait annuler ce problème car comme je l'avais pensé, chaque matrice serait par rapport a son image, donc pas une image par rapport à l'autre comme le code de darkDragon qui a fonctionné nickel que tant que je prenais les caractères sur la même page que je comparais la bande (Car même hauteur), mais quand j'ai voulu faire une demo a un copain, "je me suis trouvé couille et bite" (Expression de ma région
) avec mes caracteres de la page 1 un peu plus petits comparant une bande de la page 2, et la ...le super dragon a eu une extinction de feu
(En attendant encore bravo quand même pour son comparateur efficace jusqu'a la)
Pour ce qui est de ton code, je l'avais vu et l'avais essayé en le trouvant efficace à l'epoque, mais je n'avais pas percuté pour mon besoin.
Car ton code compare deux images ce qui est super pour par exemple faire du tri de repertoires avec des photos redondantes, et je m'etais dit tiens ça peut etre utile...
Alors que celui de darkDragon recherchais une photo dans une autre, en se déplaçant et donne les coordonnées de cette image si il la trouve, et c'est ça qui fait toute la différence, et ça j'en avais sacrement besoin
Car j'avais essayé de piloter IE en reperant des parties d'ecran, pour deplacer la souris a cette position et la faire cliquer, j'avais aussi ouvert un POST sur ce forum a ce sujet, pour avoir un peu d'aide de matheux encore une fois, car je recherchais dans toute la page et ce code etait trop long
Alors tout naturellement c'est vers ce code que je ma premiere idée est venue, car il m'avait trop épaté, et en plus etait encore mieux adapté puisqu'il ne compare pas deux image mais en recherche une dans l'autre et c'est mon cas car si elles sont pas exactement bien calées comme on l'a dit au dessus..ça va "merder"
En tout cas mille merci DOBRO de ta précieuse aide
Je vais regarder ça de plus pres, mais grâce à vous je reprend espoir
@FrenchyPilou
Merci pour les liens je vais aussi y jeter un oeil
Alors la l'idée de mettre tout en une seule phrase c'est fort, j'y avais pas pensé

Moi j'avais eu la même idée en utilisant un tableau, parce que bettement un tableau est "carré" donc ressemble à une matrice, mais c'est vrais que y mettre sur une ligne, c'est un peu moins lisible pour l'humain, mais surement mieux pour la machine

Pour ce qui est de la couleur, j'avais aussi pensé à la retirer, car mes essais de la semaine derniere avaient été sur des images enregistrées avec un programme SnapShot en 1 bit, en fait je savais pas ce que ça voulait dire, mais j'ai decouvert a force d'essais que moins on mettait de bit et plus le rechercheur d'image l'une dans l'autre s'en sortait.
apres j'ai vu que 1 bit ça donnait noir et blanc (Normal deux etats, mais j'ai compris qu'apres

En plus j'suis obligé, parce que ces bourrins pour corser le tout ont mis une ligne sur deux de fond de chaque couleur, et aussi une autre couleur de fond au survol de la souris

Donc pour la couleur, je devrais avoir trouvé le truc, en plus, les dieux sont un peu avec moi, car en plus de votre aide, je viens de voir un post qui convertit les images en 1 bit (On aurait dit qu'il m'avait entendu dans mes nuits

J'ai aussi remarqué que le travail en BMP est préférable, les programmes retrouvent mieux les images dans les BMP que les autres formats compressés.
Pour le callage, tu as raison, j'ai pas encore commencé la découpe des bandes mais je devrait y arriver, il suffit de scanner les pixels avec un trait comme sur un scanner en partant de la gauche par exemple, et des que l'on trouve un pixel sur la ligne qui n'est pas de la couleur du fond a priori ce devrait être le début de la lettre, si y'a pas des merdouilles autour, car j'ai aussi découverts que quand on grossi mortel l'image autour y'a des pixels qui sont ni couleur du fond, ni couleur du caractère, mais comme le dit GRom je pourrais peut être utiliser une marge d'erreur, enfin si j'y arrive

Reste le problème de la taille, car même police, mais taille différente, donc comme tu me le confirme, le fait de créer une matrice devrait annuler ce problème car comme je l'avais pensé, chaque matrice serait par rapport a son image, donc pas une image par rapport à l'autre comme le code de darkDragon qui a fonctionné nickel que tant que je prenais les caractères sur la même page que je comparais la bande (Car même hauteur), mais quand j'ai voulu faire une demo a un copain, "je me suis trouvé couille et bite" (Expression de ma région


Pour ce qui est de ton code, je l'avais vu et l'avais essayé en le trouvant efficace à l'epoque, mais je n'avais pas percuté pour mon besoin.
Car ton code compare deux images ce qui est super pour par exemple faire du tri de repertoires avec des photos redondantes, et je m'etais dit tiens ça peut etre utile...

Alors que celui de darkDragon recherchais une photo dans une autre, en se déplaçant et donne les coordonnées de cette image si il la trouve, et c'est ça qui fait toute la différence, et ça j'en avais sacrement besoin

Car j'avais essayé de piloter IE en reperant des parties d'ecran, pour deplacer la souris a cette position et la faire cliquer, j'avais aussi ouvert un POST sur ce forum a ce sujet, pour avoir un peu d'aide de matheux encore une fois, car je recherchais dans toute la page et ce code etait trop long

Alors tout naturellement c'est vers ce code que je ma premiere idée est venue, car il m'avait trop épaté, et en plus etait encore mieux adapté puisqu'il ne compare pas deux image mais en recherche une dans l'autre et c'est mon cas car si elles sont pas exactement bien calées comme on l'a dit au dessus..ça va "merder"

En tout cas mille merci DOBRO de ta précieuse aide

Je vais regarder ça de plus pres, mais grâce à vous je reprend espoir

@FrenchyPilou
Merci pour les liens je vais aussi y jeter un oeil

Re: Pour les matheux ..se contruire un mini OCR
Salut a tous !
Très intéressant votre raisonnement !
Je trouve que le plus difficile à faire sera bien la découpe :
- des lignes
- puis la découpe caractère par caractère.
Une piste : peut-être en recherchant les pixels adjacent ?
Exemple en reprenant l'idée de matrice
l1 : 00000000
l2 : 01000000
l3 : 01000000
l4 : 01000000
l5 : 01111110
l6 : 00000000
Après détection du premier pixel (couleur différente du fond), ici l2 2ème bit
Recherche des pixels adjacent de même couleur :
- 8 combinaisons possibles (boucle possible ; certaine peut être négligé : gauche et haut.. a voir au cas par cas)
- pas l2 3ème bit, pas l3 1er bit, pas l3 3ème bit....etc
seul trouvé l3 2ème bit, donc a partir de celui là faire une nouvelle recherche... ainsi de suite.
Dernier trouvé l5 7ème bit : c'est la fin de la lettre.
Cela donne donc la hauteur de ligne est la largueur de la lettre.
On peut donc :
- Traiter ce caractère (comparaison avec une matrice...etc)
- Réduire la ligne d'un caractère
- Recommence avec le suivant.
Ce ne sont que quelque idées ! (pour faire avance le schmilblick, comme dirais l'autre...)
Dans tous les cas, n'hésite pas a balancé du code ca aide a avancé !
Bonne programmation...
A+
Ulix
Très intéressant votre raisonnement !

Je trouve que le plus difficile à faire sera bien la découpe :
- des lignes
- puis la découpe caractère par caractère.
Une piste : peut-être en recherchant les pixels adjacent ?
Exemple en reprenant l'idée de matrice
l1 : 00000000
l2 : 01000000
l3 : 01000000
l4 : 01000000
l5 : 01111110
l6 : 00000000
Après détection du premier pixel (couleur différente du fond), ici l2 2ème bit
Recherche des pixels adjacent de même couleur :
- 8 combinaisons possibles (boucle possible ; certaine peut être négligé : gauche et haut.. a voir au cas par cas)
- pas l2 3ème bit, pas l3 1er bit, pas l3 3ème bit....etc
seul trouvé l3 2ème bit, donc a partir de celui là faire une nouvelle recherche... ainsi de suite.
Dernier trouvé l5 7ème bit : c'est la fin de la lettre.
Cela donne donc la hauteur de ligne est la largueur de la lettre.
On peut donc :
- Traiter ce caractère (comparaison avec une matrice...etc)
- Réduire la ligne d'un caractère
- Recommence avec le suivant.
Ce ne sont que quelque idées ! (pour faire avance le schmilblick, comme dirais l'autre...)
Dans tous les cas, n'hésite pas a balancé du code ca aide a avancé !
Bonne programmation...

A+
Ulix
Re: Pour les matheux ..se contruire un mini OCR
C'est comme ça que boss subtitle Workshop pour ceux qui connaissent.
il lit les sous titres dvd sous forme d'image et demande à quoi correspond la 1ere, on lui indique la lettre puis il continue.
On créée une suite complète et on sauve la matrice générée. Celle ci sera réutilisable pour d'autre film même si ce n'est pas dit que ça fonctionne (il faudra alors recommencer).
Il faut tout de même que le programme soit capable de détecter la hauteur de la ligne contenant les caractères.
il lit les sous titres dvd sous forme d'image et demande à quoi correspond la 1ere, on lui indique la lettre puis il continue.
On créée une suite complète et on sauve la matrice générée. Celle ci sera réutilisable pour d'autre film même si ce n'est pas dit que ça fonctionne (il faudra alors recommencer).
Il faut tout de même que le programme soit capable de détecter la hauteur de la ligne contenant les caractères.
~~~~Règles du forum ~~~~
⋅.˳˳.⋅ॱ˙˙ॱ⋅.˳Ar-S ˳.⋅ॱ˙˙ॱ⋅.˳˳.⋅
W11x64 PB 6.x
Section HORS SUJET : ICI
LDV MULTIMEDIA : Dépannage informatique & mes Logiciels PB
UPLOAD D'IMAGES : Uploader des images de vos logiciels
⋅.˳˳.⋅ॱ˙˙ॱ⋅.˳Ar-S ˳.⋅ॱ˙˙ॱ⋅.˳˳.⋅
W11x64 PB 6.x
Section HORS SUJET : ICI
LDV MULTIMEDIA : Dépannage informatique & mes Logiciels PB
UPLOAD D'IMAGES : Uploader des images de vos logiciels
- Kwai chang caine
- Messages : 6989
- Inscription : sam. 23/sept./2006 18:32
- Localisation : Isere
Re: Pour les matheux ..se contruire un mini OCR
Merci ULIX de l'idée.
J'ai eu un peu de mal a comprendre ton explication, mais en fait je connais la couleur de fond, donc je peux en déduire ou est écrit le caractère.
Le plus dur est bien sur le calage du caractère, mais aussi ces pixels perdus, qui sont ni chien ni loups.
Quand on grossi un caractère qui parait propre j'ai vu des pixels autour qui n'ont ni la couleur du fond, ni celle vraiment du caractère.
Souvent aussi pour faire l'arrondi dans les angles c'est pas vraiment la couleur du caractère et pas celle du fond.
Mais comme le dit DOBRO, quelques points devraient pouvoir déterminer la lettre, enfin j’espère.
Le tout est de faire la liste des points cruciaux de chaque lettre.
Je commencerais mercredi, car la j'suis pas au boulot, mais j'avais aussi pensé empiler les 26 lettres les unes sur les autres pour voir lesquels points ne sont pas communs, mais je pense que ça va être un gros foutoir
J'y pense maintenant, une fois les matrices faites, faire un programme qui repère les points particuliers de chaque lettre, un peu comme on pourrait dire les points "Premier" qui ne s'identifient que pour lui-meme en analogie aux nombre premiers qui ne se divisent que par 1 ou eux meme...(Putain ...KCC il a sorti l'artillerie lourde c'est la seule chose qui doit me rester de ma "carriere" mathématique scolaire
)
@Ars
J'avais aussi pensé à faire un groupe d'image par page, mais j'suis même pas sur que dans la même page les caractères ne vont pas varier d'un jour a l'autre selon si elle est plus chargé ou non.
Et puis j'me suis fait un fion comme ça rien qu'a récupérer les 10 chiffres minuscules, sans avoir commencé les 60 lettres...alors faire ça par page..sans être sur du résultat...
Ou alors y'aurais fallu que la decoupe se fasse au moins toute seule, et que l'on se tape à renommer les images, mais encore une fois sans certitude de reussite.
J'ai peur que ce soit un peu trop aléatoire tout ça
Non l'idée de DOBRO me parait cool au premier abord, je pense que je vais me lancer dans cette direction...et que trépasse si je faibli
J'ai eu un peu de mal a comprendre ton explication, mais en fait je connais la couleur de fond, donc je peux en déduire ou est écrit le caractère.
Le plus dur est bien sur le calage du caractère, mais aussi ces pixels perdus, qui sont ni chien ni loups.
Quand on grossi un caractère qui parait propre j'ai vu des pixels autour qui n'ont ni la couleur du fond, ni celle vraiment du caractère.
Souvent aussi pour faire l'arrondi dans les angles c'est pas vraiment la couleur du caractère et pas celle du fond.
Mais comme le dit DOBRO, quelques points devraient pouvoir déterminer la lettre, enfin j’espère.
Le tout est de faire la liste des points cruciaux de chaque lettre.
Je commencerais mercredi, car la j'suis pas au boulot, mais j'avais aussi pensé empiler les 26 lettres les unes sur les autres pour voir lesquels points ne sont pas communs, mais je pense que ça va être un gros foutoir
J'y pense maintenant, une fois les matrices faites, faire un programme qui repère les points particuliers de chaque lettre, un peu comme on pourrait dire les points "Premier" qui ne s'identifient que pour lui-meme en analogie aux nombre premiers qui ne se divisent que par 1 ou eux meme...(Putain ...KCC il a sorti l'artillerie lourde c'est la seule chose qui doit me rester de ma "carriere" mathématique scolaire

@Ars
J'avais aussi pensé à faire un groupe d'image par page, mais j'suis même pas sur que dans la même page les caractères ne vont pas varier d'un jour a l'autre selon si elle est plus chargé ou non.
Et puis j'me suis fait un fion comme ça rien qu'a récupérer les 10 chiffres minuscules, sans avoir commencé les 60 lettres...alors faire ça par page..sans être sur du résultat...
Ou alors y'aurais fallu que la decoupe se fasse au moins toute seule, et que l'on se tape à renommer les images, mais encore une fois sans certitude de reussite.
J'ai peur que ce soit un peu trop aléatoire tout ça

Non l'idée de DOBRO me parait cool au premier abord, je pense que je vais me lancer dans cette direction...et que trépasse si je faibli

Re: Pour les matheux ..se contruire un mini OCR
Personnellement, je pige rien au rôle que peut avoir ce
gadget Canvas
puisqu'il est incapable d'afficher une simple image

gadget Canvas
puisqu'il est incapable d'afficher une simple image

Code : Tout sélectionner
UseJPEGImageDecoder()
img = LoadImage(#PB_Any,"mon_image.jpg");Changer le chemin svp
L = ImageWidth(img)
H = ImageHeight(img)
If OpenWindow(0,0,0,L,H,"CanvasGadget", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
CanvasGadget(0,0,0,L,H)
Repeat
Event = WaitWindowEvent()
If Event = #PB_Event_Gadget And EventGadget() = 0
If EventType() = #PB_EventType_LeftButtonDown Or (EventType() = #PB_EventType_MouseMove And GetGadgetAttribute(0, #PB_Canvas_Buttons|#PB_Canvas_Image) & #PB_Canvas_LeftButton)
StartDrawing(CanvasOutput(0))
DrawImage(ImageID(img), 0, 0)
StopDrawing()
EndIf
EndIf
Until Event = #PB_Event_CloseWindow
EndIf
