IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Autres IDE Pascal Discussion :

[Scar-Divi] Détection de groupe de couleurs


Sujet :

Autres IDE Pascal

  1. #1
    Membre averti
    Avatar de Sparky95
    Homme Profil pro
    Full Stack (web) developer
    Inscrit en
    Décembre 2016
    Messages
    383
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 28
    Localisation : Belgique

    Informations professionnelles :
    Activité : Full Stack (web) developer
    Secteur : Transports

    Informations forums :
    Inscription : Décembre 2016
    Messages : 383
    Points : 367
    Points
    367
    Par défaut [Scar-Divi] Détection de groupe de couleurs
    Bonjour,
    voila j'ai un carré de 256 sur 256 et dedans un nombre x de carrés de 4 pixels (2 sur 2) tous de la même couleur.
    Je me demandais comment faire pour récupérer le nombre de fois que ce groupe apparaît ainsi que les coordonnées du pixel supérieur gauche de chaque pixel sachant que parfois les groupes peuvent se superposés et que je n'ai qu'une vue en 2D.
    Merci d'avance.
    Configuration: Scar-divi / Pascal

  2. #2
    Membre émérite

    Homme Profil pro
    Formation: Chimie et Physique (structure de la matière)
    Inscrit en
    Décembre 2010
    Messages
    1 333
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 78
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Formation: Chimie et Physique (structure de la matière)
    Secteur : Enseignement

    Informations forums :
    Inscription : Décembre 2010
    Messages : 1 333
    Points : 2 570
    Points
    2 570
    Billets dans le blog
    9
    Par défaut Pseudo-code Groupe de couleurs
    Bonjour,

    Tu cherches si j'ai bien compris à détecter les blocs de 4 pixels, de couleur uniforme, présents dans un tableau carré, d'arête égale à 256, visible sur l'écran graphique.

    La fonction GetPixel
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Function GetPixel(u, v: Integer): Word;
    renvoyant le numéro de la couleur actuelle du point de coordonnées (u, v), te donne accès aux quatre indices relatifs au bloc dont le coin supérieur gauche admet pour coordonnées (x, y):
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     h:= GetPixel(x, y);
     i:= GetPixel(x, y+1);
     j:= GetPixel(x+1, y);
     k:= GetPixel(x+1, y+1);
    Le test d'uniformité de couleur est donné au choix par l'un des algorithmes simples suivants (il y en a bien d'autres):
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     Test1:= ((h=i) AND ((h=j) AND (h=k)));
     
     s:= Abs(i - h); Inc(s, Abs(j - h)); Inc(s, Abs(k - h)); Test2:= (s=0);
     
     s:= h; 
     IF (h=i) THEN Inc(s, 50); IF (h=j) THEN Inc(s, 50);
     IF (h=k) THEN Inc(s, 50); Test3:= (s>149);
    Un inventaire méthodique te permet de repérer tous les blocs, de les dénombrer et de mémoriser les coordonnées du coin s.g., et même la couleur:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     Nb:= 0;
     FOR x:= 0 TO 254 DO
       FOR y:= 0 TO 254 DO
         IF Test(x, y, h) THEN BEGIN
                                 Inc(Nb); WriteLn(Fichier, Nb:8, x:5, y:5, h:4)
                               END;
    La dernière instruction <WriteLn> (citée de mémoire) doit sans doute être complétée, afin de conduire à une ligne lisible.
    La variable (Nb) peut être de type Word, puisqu'elle est au plus égale à 2552 = 65025 .

    Si on la déclare comme liste de 16 éléments tous initialisés à zéro:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     Nb: ARRAY[0..15] OF Word; 
    FOR h:= 0 TO 15 DO Nb[h]:= 0;
    un décompte séparé sur les 16 couleurs devient possible en introduisant la nouvelle instruction:

  3. #3
    Expert éminent sénior
    Avatar de Jipété
    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    10 919
    Détails du profil
    Informations personnelles :
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations forums :
    Inscription : Juillet 2006
    Messages : 10 919
    Points : 15 356
    Points
    15 356
    Par défaut
    Tiens, salut voisin (de forum)

    Juste une microscopique question :
    Citation Envoyé par wiwaxia Voir le message
    Un inventaire méthodique te permet de repérer tous les blocs, de les dénombrer et de mémoriser les coordonnées du coin s.g., et même la couleur:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     Nb:= 0;
     FOR x:= 0 TO 254 DO
       FOR y:= 0 TO 254 DO
         IF Test(x, y, h) THEN BEGIN
                                 Inc(Nb); WriteLn(Fichier, Nb:8, x:5, y:5, h:4)
                               END;
    Pourquoi 0 TO 254 DO et pas 0 TO 255 DO puisqu'on a 256 possibilités ?
    Merci et à l'année prochaine,

  4. #4
    Membre émérite

    Homme Profil pro
    Formation: Chimie et Physique (structure de la matière)
    Inscrit en
    Décembre 2010
    Messages
    1 333
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 78
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Formation: Chimie et Physique (structure de la matière)
    Secteur : Enseignement

    Informations forums :
    Inscription : Décembre 2010
    Messages : 1 333
    Points : 2 570
    Points
    2 570
    Billets dans le blog
    9
    Par défaut

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Pourquoi 0 TO 254 DO et pas 0 TO 255 DO puisqu'on a 256 possibilités ?
    Parce que le bloc dont le coin supérieur gauche se situe en (x, y) comporte 3 pixels sur la colonne à droite et/ou la ligne en-dessous :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     h:= GetPixel(x, y);
     i:= GetPixel(x, y+1);
     j:= GetPixel(x+1, y);
     k:= GetPixel(x+1, y+1);
    Dans un tableau déclaré ARRAY[0..(m-1), 0..(m-1)] OF Element et comportant (m2) termes, il n'y a que (m - 1)2 blocs, dont l'énumération résulte de 2 boucles imbriquées sur [0..(m-2)].

    Bon réveillon à tous !

  5. #5
    Membre averti
    Avatar de Sparky95
    Homme Profil pro
    Full Stack (web) developer
    Inscrit en
    Décembre 2016
    Messages
    383
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 28
    Localisation : Belgique

    Informations professionnelles :
    Activité : Full Stack (web) developer
    Secteur : Transports

    Informations forums :
    Inscription : Décembre 2016
    Messages : 383
    Points : 367
    Points
    367
    Par défaut
    Citation Envoyé par wiwaxia Voir le message
    Bonjour,

    Tu cherches si j'ai bien compris à détecter les blocs de 4 pixels, de couleur uniforme, présents dans un tableau carré, d'arête égale à 256, visible sur l'écran graphique.

    La fonction GetPixel
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Function GetPixel(u, v: Integer): Word;
    renvoyant le numéro de la couleur actuelle du point de coordonnées (u, v), te donne accès aux quatre indices relatifs au bloc dont le coin supérieur gauche admet pour coordonnées (x, y):
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     h:= GetPixel(x, y);
     i:= GetPixel(x, y+1);
     j:= GetPixel(x+1, y);
     k:= GetPixel(x+1, y+1);
    Le test d'uniformité de couleur est donné au choix par l'un des algorithmes simples suivants (il y en a bien d'autres):
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     Test1:= ((h=i) AND ((h=j) AND (h=k)));
     
     s:= Abs(i - h); Inc(s, Abs(j - h)); Inc(s, Abs(k - h)); Test2:= (s=0);
     
     s:= h; 
     IF (h=i) THEN Inc(s, 50); IF (h=j) THEN Inc(s, 50);
     IF (h=k) THEN Inc(s, 50); Test3:= (s>149);
    Un inventaire méthodique te permet de repérer tous les blocs, de les dénombrer et de mémoriser les coordonnées du coin s.g., et même la couleur:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     Nb:= 0;
     FOR x:= 0 TO 254 DO
       FOR y:= 0 TO 254 DO
         IF Test(x, y, h) THEN BEGIN
                                 Inc(Nb); WriteLn(Fichier, Nb:8, x:5, y:5, h:4)
                               END;
    La dernière instruction <WriteLn> (citée de mémoire) doit sans doute être complétée, afin de conduire à une ligne lisible.
    La variable (Nb) peut être de type Word, puisqu'elle est au plus égale à 2552 = 65025 .

    Si on la déclare comme liste de 16 éléments tous initialisés à zéro:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     Nb: ARRAY[0..15] OF Word; 
    FOR h:= 0 TO 15 DO Nb[h]:= 0;
    un décompte séparé sur les 16 couleurs devient possible en introduisant la nouvelle instruction:
    tout d'abord merci de votre aide,
    Oui effectivement j'ai donc un tableau avec un background et je cherche a détecter des bloques de couleur et tout ces bloques on la même couleur.
    Le truc c'est que j'emploie scar-divi qui est un compilateur qui permette de gérer plus facilement la partie détection de l'écran,... mais qui na pas les fonction prédéfinies de pascal il en à d'autres qui sont tout aussi utiles même parfois plus.
    j'avais déjà essayé de détecter toutes ces couleurs grace au code suivant (j'ai fais un bloque de 90 sur 90 pour que ce soit plus petit)

    Nom : test.png
Affichages : 398
Taille : 399 octets

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    program New;
    var 
      Points : TPointArray;
      Idx, Len : Integer;
      P : TPoint;
     
    begin
      if FindColorEx(Points, 1721408, 0, 0, 90, 90) then // retourne un tableau contenant toutes les coordonnées détectée de la couleur
      begin
        Len := Length(Points);
        for idx := 0 to Len - 1 do
        begin
          P := Points[Idx];
          WriteLn(IntToStr(P.X) + ', ' + IntToStr(P.Y));
          Inc(P.X);//j'incrémente pour exclure le x+1 des points
          //Pas trop d'idée pour exclude le y+1 de chaque point
         // ainsi que le x+1, y+1 
        end;
      end;
    end.
    mais le problème étant qu'il me retourne les coordonnées du haut de chaque bloque ainsi qu du bas évidement et je ne sais pas comment exclure la partie basse de chaque bloque.
    J'ai d'abord pensé à incrémenter aussi a chaque fois l'Y mais après me suis fais la réflexion qu'il n'irait jamais à la fin de la ligne alrs quand il en trouverait 1



    Ajout
    devrais-je peut être faire une deuxième boucle ou j'enregistre les point déjà trouvé dans le tableau le parcourir pour comparer avec le point actuel? Car je n'ai pas trop d'autre idée

    Rectification
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
     Inc(P.X);//j'incrémente pour exclure le x+1 des points
    pour
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
     Inc(Idx);//j'incrémente pour exclure le x+1 des points

  6. #6
    Membre émérite

    Homme Profil pro
    Formation: Chimie et Physique (structure de la matière)
    Inscrit en
    Décembre 2010
    Messages
    1 333
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 78
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Formation: Chimie et Physique (structure de la matière)
    Secteur : Enseignement

    Informations forums :
    Inscription : Décembre 2010
    Messages : 1 333
    Points : 2 570
    Points
    2 570
    Billets dans le blog
    9
    Par défaut Pseudo-code Groupe de couleurs
    Intéressant, ce compilateur qui utilise le langage Pascal ... mais seul un utilisateur aguerri pourra te fournir une réponse complète.
    Quelques remarques, simplement, après lecture du texte:

    1°) Quelles sont les dimensions du tableau proposé ? 90×90 ou 91×91 ? Car j'ai l'impression d'informations contradictoires:
    ... j'ai fait un bloc de 90 sur 90 pour que ce soit plus petit ...
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
     ... if FindColorEx(Points, 1721408, 0, 0, 90, 90) then ...
    2°) Quelle est la valeur de l'entier (Len) ? 90 ou 902 , 91 ou 912 , ou une valeur plus faible ? Je n'ai pas compris quelle est la boucle décrite - on n'en voit d'ailleurs qu'une seule, ce qui suppose un parcours de tous les éléments d'un tableau unidimensionnel (*):
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
        for idx := 0 to Len - 1 do
        begin
          P := Points[Idx];
          WriteLn(IntToStr(P.X) + ', ' + IntToStr(P.Y));
          Inc(P.X); 
        end
    (*) j'aurais dû y penser, (Len) est la longueur de la liste.
    Les instructions semblent correspondre à la copie des coordonnées de tous les points listés - un couple (P.X, P.Y) par ligne; ce qui suppose que la sélection des blocs monochromes de 4 pixels a été faite dès le départ ... ou dans un autre programme (ou une autre macro). De quel ensemble de pixels est-tu parti ? Du tableau nommé Points, sans doute ... Mais qu'y a-t-il dans chacun de ses éléments: les coordonnées (x, y), et la couleur, sous forme de triplet (r, v, b) ?

    3°) On en vient à ce qui aurait dû être posé en premier lieu: à quoi correspond la fonction booléenne FindColorEx(...), que représentent ses arguments (notamment les deux premiers: (Points, 1721408, ... ) .
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
     ... if FindColorEx(Points, 1721408, 0, 0, 90, 90) then ...
    Après quelques explications, on pourrait peut-être ébaucher un algorithme ...
    Avec un peu de chance, ton travail de traduction restera assez limité.

  7. #7
    Membre averti
    Avatar de Sparky95
    Homme Profil pro
    Full Stack (web) developer
    Inscrit en
    Décembre 2016
    Messages
    383
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 28
    Localisation : Belgique

    Informations professionnelles :
    Activité : Full Stack (web) developer
    Secteur : Transports

    Informations forums :
    Inscription : Décembre 2016
    Messages : 383
    Points : 367
    Points
    367
    Par défaut
    Citation Envoyé par wiwaxia Voir le message
    Intéressant, ce compilateur qui utilise le langage Pascal ... mais seul un utilisateur aguerri pourra te fournir une réponse complète.
    Quelques remarques, simplement, après lecture du texte:

    1°) Quelles sont les dimensions du tableau proposé ? 90×90 ou 91×91 ? Car j'ai l'impression d'informations contradictoires:
    effectivement je me suis trompé alrs qu'on venaient d'en parler juste avant

  8. #8
    Membre averti
    Avatar de Sparky95
    Homme Profil pro
    Full Stack (web) developer
    Inscrit en
    Décembre 2016
    Messages
    383
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 28
    Localisation : Belgique

    Informations professionnelles :
    Activité : Full Stack (web) developer
    Secteur : Transports

    Informations forums :
    Inscription : Décembre 2016
    Messages : 383
    Points : 367
    Points
    367
    Par défaut
    Citation Envoyé par wiwaxia Voir le message
    2°) Quelle est la valeur de l'entier (Len) ? 90 ou 902 , 91 ou 912 , ou une valeur plus faible ? Je n'ai pas compris quelle est la boucle décrite - on n'en voit d'ailleurs qu'une seule, ce qui suppose un parcours de tous les éléments d'un tableau unidimensionnel (*):
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
        for idx := 0 to Len - 1 do
        begin
          P := Points[Idx];
          WriteLn(IntToStr(P.X) + ', ' + IntToStr(P.Y));
          Inc(P.X); 
        end
    (*) j'aurais dû y penser, (Len) est la longueur de la liste.
    Les instructions semblent correspondre à la copie des coordonnées de tous les points listés - un couple (P.X, P.Y) par ligne; ce qui suppose que la sélection des blocs monochromes de 4 pixels a été faite dès le départ ... ou dans un autre programme (ou une autre macro). De quel ensemble de pixels est-tu parti ?
    LEN retourne 16 dans ce cas si car il y a 16 pixels de la mm couleur

  9. #9
    Membre averti
    Avatar de Sparky95
    Homme Profil pro
    Full Stack (web) developer
    Inscrit en
    Décembre 2016
    Messages
    383
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 28
    Localisation : Belgique

    Informations professionnelles :
    Activité : Full Stack (web) developer
    Secteur : Transports

    Informations forums :
    Inscription : Décembre 2016
    Messages : 383
    Points : 367
    Points
    367
    Par défaut
    Citation Envoyé par wiwaxia Voir le message
    3°) On en vient à ce qui aurait dû être posé en premier lieu: à quoi correspond la fonction booléenne FindColorEx(...), que représentent ses arguments (notamment les deux premiers: (Points, 1721408, ... ) .
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
     ... if FindColorEx(Points, 1721408, 0, 0, 90, 90) then ...
    Après quelques explications, on pourrait peut-être ébaucher un algorithme ...
    Avec un peu de chance, ton travail de traduction restera assez limité.
    et oui effectivement j'ai oublié de remettre les types demandés par la fonction (pointarray, color, xs, ys, xe, ye):boolean

  10. #10
    Membre averti
    Avatar de Sparky95
    Homme Profil pro
    Full Stack (web) developer
    Inscrit en
    Décembre 2016
    Messages
    383
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 28
    Localisation : Belgique

    Informations professionnelles :
    Activité : Full Stack (web) developer
    Secteur : Transports

    Informations forums :
    Inscription : Décembre 2016
    Messages : 383
    Points : 367
    Points
    367
    Par défaut
    c'est vrais que j'aurais du rajouter des commentaire :p
    donc en claire:
    - FindColorEx retourne un boolean si il trouve des points
    FindColorEx(out Points: TPointArray, Color: LongInt, Xs:LongIng, Ys:LongIng, Xe:LongIng, Ye:LongIng): boolean;

    -Len
    taille du tableau (nombre de fois que le pixel à été trouvé)

    -P := Points[Idx];
    les coordonnées de chaque point

  11. #11
    Membre émérite

    Homme Profil pro
    Formation: Chimie et Physique (structure de la matière)
    Inscrit en
    Décembre 2010
    Messages
    1 333
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 78
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Formation: Chimie et Physique (structure de la matière)
    Secteur : Enseignement

    Informations forums :
    Inscription : Décembre 2010
    Messages : 1 333
    Points : 2 570
    Points
    2 570
    Billets dans le blog
    9
    Par défaut Pseudo-code Groupe de couleurs
    Je crois comprendre: FindColorEx(Points, N, X1, Y1, X2, Y2) renvoie la valeur (True) dès le repérage d'un pixel de couleur N - sans doute définie par une relation du type N = r + v*256 + b*2562 , ou l'inverse, peu importe ici - dans un rectangle dont les coordonnées vérifient les conditions d'encadrement:
    (X1 <= x <= X2) et (Y1 <= y <= Y2) ;
    les coordonnées correspondantes sont progressivement archivées dans la liste (Points), qu'il suffit par la suite d'afficher à l'écran ou de copier dans un fichier texte.

    Il va de soi qu'avec plus de 16 millions de couleurs (2563) la probabilité de trouver un bloc monochrome de 4 pixels contigus est bien faible ... Tu n'en a trouvé toi-même pour une couleur donnée (N = 1721408) que 16, dispersés dans une matrice à plus de 8000 éléments (902 ou 912) .
    Plus rien à voir avec la palette rudimentaire à 16 couleurs du Pascal, comme je l'imaginais d'une manière un peu simpliste.

    Pour en revenir à l'essentiel, la fonction utilisée ne convient pas du tout, parce qu'elle effectue une recherche de pixels de couleur prédéfinie, alors que le problème initial est de trouver (selon tes propres termes) des
    ... carrés de 4 pixels (2 sur 2) tous de la même couleur ...
    Il n'est pas étonnant que tu te sois fourvoyé dans une impasse.

    Tu trouveras certainement dans l'éventail des fonctions proposées (je n'ai pas eu le temps de regarder) quelque chose du genre:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
     FUNCTION Couleur_Pixel(x, y: LongInt): LongInt
    qui s'intégrera sans difficulté à ce qui a été proposé au début.

    Là, il me faut m'arrêter. On pourra reprendre cet échange ultérieurement, mais sans doute pas avant l'année prochaine.

    Bonne soirée !

  12. #12
    Membre averti
    Avatar de Sparky95
    Homme Profil pro
    Full Stack (web) developer
    Inscrit en
    Décembre 2016
    Messages
    383
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 28
    Localisation : Belgique

    Informations professionnelles :
    Activité : Full Stack (web) developer
    Secteur : Transports

    Informations forums :
    Inscription : Décembre 2016
    Messages : 383
    Points : 367
    Points
    367
    Par défaut
    Citation Envoyé par wiwaxia Voir le message
    Je crois comprendre: FindColorEx(Points, N, X1, Y1, X2, Y2) renvoie la valeur (True) dès le repérage d'un pixel de couleur N - sans doute définie par une relation du type N = r + v*256 + b*2562 , ou l'inverse, peu importe ici - dans un rectangle dont les coordonnées vérifient les conditions d'encadrement:
    (X1 <= x <= X2) et (Y1 <= y <= Y2) ;
    les coordonnées correspondantes sont progressivement archivées dans la liste (Points), qu'il suffit par la suite d'afficher à l'écran ou de copier dans un fichier texte.

    Il va de soi qu'avec plus de 16 millions de couleurs (2563) la probabilité de trouver un bloc monochrome de 4 pixels contigus est bien faible ... Tu n'en a trouvé toi-même pour une couleur donnée (N = 1721408) que 16, dispersés dans une matrice à plus de 8000 éléments (902 ou 912) .
    Plus rien à voir avec la palette rudimentaire à 16 couleurs du Pascal, comme je l'imaginais d'une manière un peu simpliste.

    Pour en revenir à l'essentiel, la fonction utilisée ne convient pas du tout, parce qu'elle effectue une recherche de pixels de couleur prédéfinie, alors que le problème initial est de trouver (selon tes propres termes) des

    Il n'est pas étonnant que tu te sois fourvoyé dans une impasse.

    Tu trouveras certainement dans l'éventail des fonctions proposées (je n'ai pas eu le temps de regarder) quelque chose du genre:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
     FUNCTION Couleur_Pixel(x, y: LongInt): LongInt
    qui s'intégrera sans difficulté à ce qui a été proposé au début.

    Là, il me faut m'arrêter. On pourra reprendre cet échange ultérieurement, mais sans doute pas avant l'année prochaine.

    Bonne soirée !
    Oui il y a GetColor(x, y); mais oui mon bute était d'abord de faire le code avec des valeurs fixes puis d'en faire une fonction que j’inclurai dans mes codes ce que je fais en fait lorsque je fais des fonction je les écris à la mode barbare avec des valeurs fixes puis une fois qu'elle fonctionne je modifier les valeurs fixes en variables et je regarde lesquels je fais passer en paramètres et lesquels je défini que pour la fonction, ...

    Et n'oublions pas BONNE et HEUREUSE année ;-)

  13. #13
    Membre émérite

    Homme Profil pro
    Formation: Chimie et Physique (structure de la matière)
    Inscrit en
    Décembre 2010
    Messages
    1 333
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 78
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Formation: Chimie et Physique (structure de la matière)
    Secteur : Enseignement

    Informations forums :
    Inscription : Décembre 2010
    Messages : 1 333
    Points : 2 570
    Points
    2 570
    Billets dans le blog
    9
    Par défaut Pseudo-code Groupe de couleurs
    Bonjour,

    J'ai téléchargé (sans installer) le logiciel SCAR Divi, mais vainement tenté d'obtenir le manuel correspondant proposé sur le forum, afin de consulter la liste des fonctions disponibles: SCAR Divi Manual You can find the SCAR Divi manual here.
    Mes trois navigateurs (FF, IE et Opera) refusent la connexion avec une belle unanimité pour des raisons de sécurité :
    La connexion n’est pas sécurisée
    Les propriétaires de wiki.scar-divi.com ont mal configuré leur site web. Pour éviter que vos données ne soient dérobées, Firefox ne s’est pas connecté à ce site web.
    wiki.scar-divi.com utilise un certificat de sécurité invalide.

    Le certificat de sécurité de ce site Web présente un problème.
    Le certificat de sécurité présenté par ce site Web a été émis pour une autre adresse de site Web.
    Les problèmes de certificat de sécurité peuvent indiquer une tentative de duperie ou d’interception des données que vous envoyez sur le serveur.
    Et en passant outre l'avertissement, je me suis retrouvé dans une boucle alternée (accueil/forum).

    Pour en revenir à la méthode que tu as voulu mettre en oeuvre:
    ... mon but était d'abord de faire le code avec des valeurs fixes puis d'en faire une fonction que j’inclurais dans mes codes, ce que je fais en fait lorsque je fais des fonctions je les écris à la mode barbare avec des valeurs fixes puis une fois qu'elles fonctionnent je modifie les valeurs fixes en variables et je regarde lesquelles je fais passer en paramètres et lesquelles je définis que pour la fonction ...
    pourquoi pas, en effet ? ... sauf que ce qui était envisageable avec la palette élémentaire à 16 couleurs du Pascal ne l'est plus du tout lorsqu'il faut en tester 16777216 ! On en revient à la nécessité de ne pas fixer la couleur au préalable.

    La fonction initialement proposée (FindColorEx( ... )) pourrait être avantageusement utilisée, sous réserve d'une délimitation stricte du domaine exploré:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     CONST w = 90;
     VAR Len: Byte; N, u, v: LongInt; Test: Boolean;
         Points : TPointArray; P: TPoint;
     FOR u:= 0 TO (w-2) DO
       FOR v:= 0 TO (w-2) DO
         BEGIN
           N:= Couleur_Pixel(u, v);                                  // Notation neutre, à remplacer    
           Test:= FindColorEx(Points, N, u, v, u+1, v+1);
           IF Test THEN BEGIN
                          Len:= Lenght(Points);                      // Len <= 4  
                          IF (Len=4) THEN WriteLn(IntToStr(u) + ', ' + IntToStr(v))    
                        END           
         END;
    Il y a sûrement des bourdes dans ce code, mais sa finalité devrait rester compréhensible.

    Je serais curieux de mieux connaître SCAR Divi, découvert en cette occasion, mais si tout est en anglais et le mode d'emploi indisponible, j'aurai du mal à dépasser le stade pro "Hello world".

    Quoi qu'il en soit, bonne et heureuse année !

  14. #14
    Membre averti
    Avatar de Sparky95
    Homme Profil pro
    Full Stack (web) developer
    Inscrit en
    Décembre 2016
    Messages
    383
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 28
    Localisation : Belgique

    Informations professionnelles :
    Activité : Full Stack (web) developer
    Secteur : Transports

    Informations forums :
    Inscription : Décembre 2016
    Messages : 383
    Points : 367
    Points
    367
    Par défaut

    bonjour,
    oui effectivement le site scar-divi est indisponible depuis un petit temps et je ne sais pas si ca va durer
    https://www.youtube.com/user/scardivicom peut peut-être vous aider pour le moment

    Dans votre code, vous mettez N Couleur_Pixel(u, v); mais je connais déjà la couleur donc pq mettre ça?
    j'ai donc mis en commentaire la ligne et défini dans les constante la couleur que je recherche et je tourne en boucle infinie

    Parcontre vous venez de me donner une idée et je ne comprend pas pourquoi comme un con je n'y ai pas pensé plus tot

    Nice elle fonctionne en plus
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
     
    program New;
    const couleur = 14418175;
    var 
      Points : TPointArray;
      Idx, Len, couleur2, couleur3, couleur4 : Integer;
      P : TPoint;
     
    begin
      if FindColorEx(Points, couleur, 0, 0, 90, 90) then // retourne un tableau contenant toutes les coordonnées détectée de la couleur
      begin
        Len := Length(Points);
        for idx := 0 to Len - 1 do
        begin
          P := Points[Idx];
          // pas très utile à vérifier peut-etre?
          //vu que quand on trouve la couleur le 2e pixel est obligatoirement de la même couleur
          //couleur2 := GetColor(P.X + 1, P.Y);
          couleur3 := GetColor(P.X, P.Y + 1);
          couleur4 := GetColor(P.X + 1, P.Y + 1);
          if{(couleur2 = couleur) and} (couleur3 = couleur) and (couleur4 = couleur) then
          WriteLn(IntToStr(P.X) + ', ' + IntToStr(P.Y));
          Inc(P.X); //On exclus diret le PX+1
        end;
      end;
    end.
    En plus c'est ce qui était plus ou moins proposé depuis le début navré de vous avoir fais perdre votre tmps :p
    Mrc bcp
    maintenant si vous avez encore un peut de courage et de tmps pour moi pourrions nous voir ensemble pour la suite de ma fonction?
    donc l'idée est la suivante j'ai un bloque d'une couleur disons brun (4 pixels) et j'ai donc x bloques de l'autre
    je viens de déterminer comment trouver les bloques(disons ici rouge)


    donc le bloque brun => FindColor(x, y, brun, xs, ys, xe, ye)
    les bloques rouges => le bout de code que l'on viens de faire

    maintenant je dois trouver quel bloque est le plus pres du bloque brun.
    que serait le mieux? faire directement dans la fonction la détection puis la comparaisson?
    ou retourner un tableau puis le trier avant de comprarer? ou une autre idée?
    perso je pensais directement le faire pendant que je recherche les bloques rouges?

    Merci d'avance


    PS: voici le code mis sous fonction

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    procedure BloqueDe4x4(couleur, xs, ys, xe, ye : integer);
    var 
      Points : TPointArray;
      Idx, Len, couleur2, couleur3, couleur4 : Integer;
      P : TPoint;
    begin
      if FindColorEx(Points, couleur, xs, ys, xe, ye) then // retourne un tableau contenant toutes les coordonnées détectée de la couleur
      begin
        Len := Length(Points);
        for idx := 0 to Len - 1 do
        begin
          P := Points[Idx];
          // pas très utile à vérifier peut-etre?
          //vu que quand on trouve la couleur le 2e pixel est obligatoirement de la même couleur
          //couleur2 := GetColor(P.X + 1, P.Y);
          couleur3 := GetColor(P.X, P.Y + 1);
          couleur4 := GetColor(P.X + 1, P.Y + 1);
          if{(couleur2 = couleur) and} (couleur3 = couleur) and (couleur4 = couleur) then
          begin
            WriteLn(IntToStr(P.X) + ', ' + IntToStr(P.Y));
            Inc(Idx); //On exclus diret le PX+1
          end;
        end;
      end;
    end;

  15. #15
    Membre émérite

    Homme Profil pro
    Formation: Chimie et Physique (structure de la matière)
    Inscrit en
    Décembre 2010
    Messages
    1 333
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 78
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Formation: Chimie et Physique (structure de la matière)
    Secteur : Enseignement

    Informations forums :
    Inscription : Décembre 2010
    Messages : 1 333
    Points : 2 570
    Points
    2 570
    Billets dans le blog
    9
    Par défaut Pseudo-code Groupe de couleurs
    Citation Envoyé par Pyton-Sparky Voir le message
    ... oui effectivement le site scar-divi est indisponible depuis un petit temps et je ne sais pas si ca va durer
    https://www.youtube.com/user/scardivicom peut peut-être vous aider pour le moment ...
    Merci pour le lien, je verrai ce que je peux en tirer.

    # Un malentendu s'est peut-être installé dans l'échange, ou un élément décisif de l'énoncé ou de l'algorithme m'a totalement échappé ... En effet:

    1°)
    Citation Envoyé par Pyton-Sparky Voir le message
    ... Dans votre code, vous mettez N Couleur_Pixel(u, v); mais je connais déjà la couleur donc pq mettre ça? ...
    Parce qu'il s'agit, selon l'énoncé initial du problème, de trouver un bloc de
    4 pixels (2 sur 2) tous de la même couleur
    et non pas d'une couleur donnée, d'après ce qui ressort implicitement de ta solution: introduire d'emblée un indice de couleur en constante
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    const couleur = 14418175;
    contredit formellement l'énoncé.

    2°)
    Citation Envoyé par Pyton-Sparky Voir le message
    ... Nice elle fonctionne en plus ...
    La valeur posée était donc la bonne, sur un ensemble qui en comporte plus de 16 millions ! La probabilité d'obtenir fortuitement un résultat est certes plus élevée que celle de gagner au Loto, mais quand même ... Cette couleur était donc connue, par une voie externe au programme.

    3°) En regardant bien le bloc d'instructions:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
          P := Points[Idx];
          couleur2 := GetColor(P.X + 1, P.Y);
          couleur3 := GetColor(P.X, P.Y + 1);
          couleur4 := GetColor(P.X + 1, P.Y + 1);
          if{(couleur2 = couleur) and} (couleur3 = couleur) and (couleur4 = couleur) then
          WriteLn(IntToStr(P.X) + ', ' + IntToStr(P.Y));
    est-ce que les lignes suivantes, déjà proposées sous une autre forme:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
          couleur:= GetColor(u, v); 
          if FindColorEx(Points, couleur, u, v, u + 1, v + 1)
            begin
               Len:= Lenght(Points);                  
               IF (Len=4) THEN WriteLn(IntToStr(u) + ', ' + IntToStr(v)) 
            end;
    ne feraient pas la même chose, à quelques détails près ? La fonction en cause FindColorEx( ... ) est alors utilisée d'une manière beaucoup plus retreinte et rapide, sur le bloc de 4 pixels.

    Il manque en fait une donnée implicite, l'image sur laquelle on travaille, sans doute en relation directe avec la matrice Points; s'agit-il d'une image visible dans une fenêtre de l'écran ? d'une image bitmap ? Comment sait-on que telle ou telle teinte est présente ?

    # La dernière question met en cause la proximité des couleurs, donc la notion d'écart entre 2 triplets d'entiers (r, v, b) et (r', v', b');
    la notion qui pourrait ici intervenir (mais pas nécessairement) est la distance de Manhattan d = |r - r'| + |v - v'| + |b - b'| .

    1°) J'ai retrouvé la formule de codification des couleurs en entiers longs, conforme à ce que j'avais donné intuitivement:
    FAQ Visual Basic Question 147 : Comment convertir une valeur long en RGB ?
    Les couleurs Windows sont représentés par un entier long (8 bytes). Cet entier long permet de stocker les composantes RVB (Rouge, Vert et Bleu) de la façon suivante : &H00BBVVRR. On remarquera que les valeurs pour R, V et B sont stockés dans l'ordre B, V, R, contrairement à HTML, par exemple, où les valeurs sont stockés dans l'ordre R, V, B.
    La fonction RGB(r,v,b) produit un entier long (Long) suivant la formule : lColorValue = 65536 * b + 256 * v + r .

    SCAR Divi, dont des commandes font référence au format Bitmap, respecte sans doute la convention de Windows (tu es mieux placé que moi pour vérifier).

    2°) La sélection la plus contraignante exigerait de définir pour chaque couleur fondamentale un domaine ouvert de valeurs admissibles (]I1 ; I2[) puis d'entreprendre un balayage complet de l'image pour filtrer les pixels de couleur appropriée, par exemple:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     CONST B1 = 256; B2 = B1 * B1;
    FOR x:= 0 TO Xm DO
       FOR y:= 0 TO Ym DO
         BEGIN
           N:= GetColor(x, y); r:= N MOD B1; b:= N DIV B2;
           v:= (N - r) DIV B1; Dec(v, B1 * b);
           TestR:= ((R1<r) AND (r<R2)); etc ...
           Test:= (TestR AND (TestV AND TestB));
           IF Test THEN <enregistrer x, y, (r, v, b)>     
         END;

  16. #16
    Membre averti
    Avatar de Sparky95
    Homme Profil pro
    Full Stack (web) developer
    Inscrit en
    Décembre 2016
    Messages
    383
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 28
    Localisation : Belgique

    Informations professionnelles :
    Activité : Full Stack (web) developer
    Secteur : Transports

    Informations forums :
    Inscription : Décembre 2016
    Messages : 383
    Points : 367
    Points
    367
    Par défaut
    Citation Envoyé par wiwaxia Voir le message
    Merci pour le lien, je verrai ce que je peux en tirer.

    # Un malentendu s'est peut-être installé dans l'échange, ou un élément décisif de l'énoncé ou de l'algorithme m'a totalement échappé ... En effet:

    1°)

    Parce qu'il s'agit, selon l'énoncé initial du problème, de trouver un bloc de

    et non pas d'une couleur donnée, d'après ce qui ressort implicitement de ta solution: introduire d'emblée un indice de couleur en constante
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    const couleur = 14418175;
    contredit formellement l'énoncé.
    2°)

    La valeur posée était donc la bonne, sur un ensemble qui en comporte plus de 16 millions ! La probabilité d'obtenir fortuitement un résultat est certes plus élevée que celle de gagner au Loto, mais quand même ... Cette couleur était donc connue, par une voie externe au programme.
    Oui effectivement je me suis gouré dans l'énoncé. On fournis la couleur demandée.

    Citation Envoyé par wiwaxia Voir le message
    3°) En regardant bien le bloc d'instructions:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
          P := Points[Idx];
          couleur2 := GetColor(P.X + 1, P.Y);
          couleur3 := GetColor(P.X, P.Y + 1);
          couleur4 := GetColor(P.X + 1, P.Y + 1);
          if{(couleur2 = couleur) and} (couleur3 = couleur) and (couleur4 = couleur) then
          WriteLn(IntToStr(P.X) + ', ' + IntToStr(P.Y));
    est-ce que les lignes suivantes, déjà proposées sous une autre forme:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
          couleur:= GetColor(u, v); 
          if FindColorEx(Points, couleur, u, v, u + 1, v + 1)
            begin
               Len:= Lenght(Points);                  
               IF (Len=4) THEN WriteLn(IntToStr(u) + ', ' + IntToStr(v)) 
            end;
    ne feraient pas la même chose, à quelques détails près ? La fonction en cause FindColorEx( ... ) est alors utilisée d'une manière beaucoup plus retreinte et rapide, sur le bloc de 4 pixels.
    Non car il ne me donne que le pixel 1 bisarrement :/ ou alrs je l'ai mal fais
    Citation Envoyé par wiwaxia Voir le message
    Bizarrement ce n'est pas la même chose
    Il manque en fait une donnée implicite, l'image sur laquelle on travaille, sans doute en relation directe avec la matrice Points; s'agit-il d'une image visible dans une fenêtre de l'écran ? d'une image bitmap ? Comment sait-on que telle ou telle teinte est présente ?
    en effet il s'agit de l'image a l'écran en fait scar-divi travail directement avec l'écran actif
    Citation Envoyé par wiwaxia Voir le message
    # La dernière question met en cause la proximité des couleurs, donc la notion d'écart entre 2 triplets d'entiers (r, v, b) et (r', v', b');
    la notion qui pourrait ici intervenir (mais pas nécessairement) est la distance de Manhattan d = |r - r'| + |v - v'| + |b - b'| .
    pas trop compris :p

    Citation Envoyé par wiwaxia Voir le message
    1°) J'ai retrouvé la formule de codification des couleurs en entiers longs, conforme à ce que j'avais donné intuitivement:
    FAQ Visual Basic Question 147 : Comment convertir une valeur long en RGB ?
    Les couleurs Windows sont représentés par un entier long (8 bytes). Cet entier long permet de stocker les composantes RVB (Rouge, Vert et Bleu) de la façon suivante : &H00BBVVRR. On remarquera que les valeurs pour R, V et B sont stockés dans l'ordre B, V, R, contrairement à HTML, par exemple, où les valeurs sont stockés dans l'ordre R, V, B.
    La fonction RGB(r,v,b) produit un entier long (Long) suivant la formule : lColorValue = 65536 * b + 256 * v + r .

    SCAR Divi, dont des commandes font référence au format Bitmap, respecte sans doute la convention de Windows (tu es mieux placé que moi pour vérifier).
    pas trop compris nn plus mais si vous vous demandé comment j'options ce sombre c'est via le pick color(ctrl + P) par défaut

    Citation Envoyé par wiwaxia Voir le message
    2°) La sélection la plus contraignante exigerait de définir pour chaque couleur fondamentale un domaine ouvert de valeurs admissibles (]I1 ; I2[) puis d'entreprendre un balayage complet de l'image pour filtrer les pixels de couleur appropriée, par exemple:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     CONST B1 = 256; B2 = B1 * B1;
    FOR x:= 0 TO Xm DO
       FOR y:= 0 TO Ym DO
         BEGIN
           N:= GetColor(x, y); r:= N MOD B1; b:= N DIV B2;
           v:= (N - r) DIV B1; Dec(v, B1 * b);
           TestR:= ((R1<r) AND (r<R2)); etc ...
           Test:= (TestR AND (TestV AND TestB));
           IF Test THEN <enregistrer x, y, (r, v, b)>     
         END;
    pas comrpis nn plus :/



    navré du temps qu'il m'a fallut mais j'ai pas tout comrpis du coup j'ai du relire plusieurs fois puis j'ai été appelé à la rescousse pour un serveur ...

  17. #17
    Membre émérite

    Homme Profil pro
    Formation: Chimie et Physique (structure de la matière)
    Inscrit en
    Décembre 2010
    Messages
    1 333
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 78
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Formation: Chimie et Physique (structure de la matière)
    Secteur : Enseignement

    Informations forums :
    Inscription : Décembre 2010
    Messages : 1 333
    Points : 2 570
    Points
    2 570
    Billets dans le blog
    9
    Par défaut
    Bonjour,

    Le nombre de sujets abordés dans le dernier message m'a conduit à répondre brièvement, et parfois d'une manière beaucoup trop rapide; il n'est donc pas étonnant que certains résultats t'aient paru franchement parachutés.
    Je reviens sur quelques points particuliers.

    1°) La conversion (r, v, b)/entier long: le codage des couleurs, initialement représentées par un triplet de Bytes (r, v, b), peut se réduire à un entier unique de type LongInt donné par la combinaison linéaire (0): N = r + (256 * v) + (2562 * b) .
    De cette relation de définition, on peut en déduire trois autres, qui n'en diffèrent que par la présentation:
    (1) N = r + 256 * (v + (256 * b))
    (2) N = (r + (256 * v)) + (2562) * b
    (3) N - r = 256 * (v + (256 * b))
    mais montrent comment remonter aux trois indices de couleur par des divisions euclidiennes:
    (1') r = N MOD 256 // reste de la d.e. de N par 256
    (2') b = N DIV (2562) // quotient de la d.e. de N par 2562 = 65536
    (3') (N - r) DIV 256 = v + (256 * b) d'où le dernier résultat: (3") v = ((N - r) DIV 256) - (256 * b)
    Ces résultats se traduisent en Pascal par les 4 instructions suivantes:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
           r:= N MOD B1;       b:= N DIV B2;  // avec B1 = 256 et B2 = B1 * B1
           v:= (N - r) DIV B1; Dec(v, B1 * b);
    2°) Repérer des couleurs proches d'une couleur donnée revient à définir l'écart entre deux triplets d'entiers (r, v, b) et (R0, V0, B0) - valeur de référence.

    a) On conviendra que deux couleurs sont apparentées si les écarts entre les indices correspondants ne dépassent pas en valeur absolue une limite convenue, par exemple:
    # |r - R0| < Er
    # |v - V0| < Ev
    # |b - B0| < Eb
    conditions équivalentes aux suivantes (nettement plus lourdes au codage, je le vois maintenant):
    # (R0 - Er) < r < (R0 + Er)
    # (V0 - Ev) < v < (V0 + Ev)
    # (B0 - Eb) < b < (B0 + Eb)
    Ces conditions se traduiront en Pascal par:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
          TestR:= (Abs(r - R0) < Er);
          TestV:= (Abs(v - V0) < Ev);
          TestB:= (Abs(b - B0) < Eb);
          Test:= (TestR AND (TestV AND TestB));    // Test (1) de couleurs "proches"
    instructions qui remplaceront avantageusement ce qui avait été rapidement proposé:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
          TestR:= ((R1<r) AND (r<R2));    // etc ... 6 constantes à définir! R1, R2, V1, V2, Bl1, Bl2
    b) Une autre méthode consiste à évaluer la distance séparant les deux triplets d'entiers par la somme des valeurs absolues des écarts (distance de Manhattan):
    D = |r - R0| + |v - V0| + |b - B0| .
    Le test de proximité des couleurs (D < Dmax) est plus souple, dans la mesure où il autorise une compensation des écarts; il se traduit par les instructions:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
          d:= Abs(r - R0);     Inc(d, Abs(v - V0)); 
          Inc(d, Abs(b - B0)); Test:= (d < Dmax);    // Test (2) de couleurs "proches"

  18. #18
    Membre averti
    Avatar de Sparky95
    Homme Profil pro
    Full Stack (web) developer
    Inscrit en
    Décembre 2016
    Messages
    383
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 28
    Localisation : Belgique

    Informations professionnelles :
    Activité : Full Stack (web) developer
    Secteur : Transports

    Informations forums :
    Inscription : Décembre 2016
    Messages : 383
    Points : 367
    Points
    367
    Par défaut
    Citation Envoyé par wiwaxia Voir le message
    Bonjour,

    Le nombre de sujets abordés dans le dernier message m'a conduit à répondre brièvement, et parfois d'une manière beaucoup trop rapide; il n'est donc pas étonnant que certains résultats t'aient paru franchement parachutés.
    Je reviens sur quelques points particuliers.

    1°) La conversion (r, v, b)/entier long: le codage des couleurs, initialement représentées par un triplet de Bytes (r, v, b), peut se réduire à un entier unique de type LongInt donné par la combinaison linéaire (0): N = r + (256 * v) + (2562 * b) .
    De cette relation de définition, on peut en déduire trois autres, qui n'en diffèrent que par la présentation:
    (1) N = r + 256 * (v + (256 * b))
    (2) N = (r + (256 * v)) + (2562) * b
    (3) N - r = 256 * (v + (256 * b))
    mais montrent comment remonter aux trois indices de couleur par des divisions euclidiennes:
    (1') r = N MOD 256 // reste de la d.e. de N par 256
    (2') b = N DIV (2562) // quotient de la d.e. de N par 2562 = 65536
    (3') (N - r) DIV 256 = v + (256 * b) d'où le dernier résultat: (3") v = ((N - r) DIV 256) - (256 * b)
    Ces résultats se traduisent en Pascal par les 4 instructions suivantes:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
           r:= N MOD B1;       b:= N DIV B2;  // avec B1 = 256 et B2 = B1 * B1
           v:= (N - r) DIV B1; Dec(v, B1 * b);
    2°) Repérer des couleurs proches d'une couleur donnée revient à définir l'écart entre deux triplets d'entiers (r, v, b) et (R0, V0, B0) - valeur de référence.

    a) On conviendra que deux couleurs sont apparentées si les écarts entre les indices correspondants ne dépassent pas en valeur absolue une limite convenue, par exemple:
    # |r - R0| < Er
    # |v - V0| < Ev
    # |b - B0| < Eb
    conditions équivalentes aux suivantes (nettement plus lourdes au codage, je le vois maintenant):
    # (R0 - Er) < r < (R0 + Er)
    # (V0 - Ev) < v < (V0 + Ev)
    # (B0 - Eb) < b < (B0 + Eb)
    Ces conditions se traduiront en Pascal par:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
          TestR:= (Abs(r - R0) < Er);
          TestV:= (Abs(v - V0) < Ev);
          TestB:= (Abs(b - B0) < Eb);
          Test:= (TestR AND (TestV AND TestB));    // Test (1) de couleurs "proches"
    instructions qui remplaceront avantageusement ce qui avait été rapidement proposé:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
          TestR:= ((R1<r) AND (r<R2));    // etc ... 6 constantes à définir! R1, R2, V1, V2, Bl1, Bl2
    b) Une autre méthode consiste à évaluer la distance séparant les deux triplets d'entiers par la somme des valeurs absolues des écarts (distance de Manhattan):
    D = |r - R0| + |v - V0| + |b - B0| .
    Le test de proximité des couleurs (D < Dmax) est plus souple, dans la mesure où il autorise une compensation des écarts; il se traduit par les instructions:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
          d:= Abs(r - R0);     Inc(d, Abs(v - V0)); 
          Inc(d, Abs(b - B0)); Test:= (d < Dmax);    // Test (2) de couleurs "proches"


    aaa ok je viens de capter je pense que vous avez mal compris ou que j'ai denouveau mal énoncé ce que j'essaye d'obtenir :s
    c'est beaucoup plus simple j'ai un block de 4 d'un couleur connue et j'ai x bloques de 4 d'un couleur aussi connue (dont on vient ensemble de faire la détection du nombre) et ce que je cherche à faire c'est détecter quel bloque est le plus proche :p

  19. #19
    Membre émérite

    Homme Profil pro
    Formation: Chimie et Physique (structure de la matière)
    Inscrit en
    Décembre 2010
    Messages
    1 333
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 78
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Formation: Chimie et Physique (structure de la matière)
    Secteur : Enseignement

    Informations forums :
    Inscription : Décembre 2010
    Messages : 1 333
    Points : 2 570
    Points
    2 570
    Billets dans le blog
    9
    Par défaut
    donc l'idée est la suivante j'ai un bloc d'une couleur disons brun (4 pixels) et j'ai donc x blocs de l'autre
    je viens de déterminer comment trouver les bloques(disons ici rouge)
    donc le bloque brun => FindColor(x, y, brun, xs, ys, xe, ye)
    les bloques rouges => le bout de code que l'on viens de faire
    maintenant je dois trouver quel bloc est le plus près du bloc brun.
    c'est beaucoup plus simple j'ai un bloc de 4 d'un couleur connue et j'ai x blocs de 4 d'un couleur aussi connue (dont on vient ensemble de faire la détection du nombre) et ce que je cherche à faire c'est détecter quel bloc est le plus proche
    Désolé, je n'avais pas vu qu'il s'agissait de proximité géométrique, caractérisée par la distance euclidienne séparant des coins supérieurs gauches.

    Il y a un bloc brun (Couleur1, coordonnées X1, Y1) et (Len) blocs rouges (Couleur2) listées dans Points. Il suffit de trouver la valeur minimale de (D2).

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
     X2:= Sqr(Xmax); Y2:=Sqr(Ymax); D2m:= X2 + Y2;     // Valeur maximale de D2min - Diagonale de l'image rectangulaire 
     FOR i:= 0 TO (Len - 1) DO                         // Je suppose que la liste des (Len) csg commence à zéro ...
       BEGIN
         X2:= Sqr(Points[i].X - X1); Y2:= Sqr(Points[i].Y - Y1); s:= X2 + Y2;
         IF (D2m>s) THEN BEGIN
                           D2m:= s; k:= i          // Nouvelle valeur plus faible de D2min; enregistrement du rang du terme correspondant
                         END
       END;  
     Xm:= Point[k].X; Ym:= Points[k].Y
    On obtient à l'issue de l'exécution de ces instructions les coordonnées (Xm, Ym) du bloc le plus proche.
    Il est possible qu'une procédure ou fonction de SCAR Divi effectue tâche analogue.

  20. #20
    Membre averti
    Avatar de Sparky95
    Homme Profil pro
    Full Stack (web) developer
    Inscrit en
    Décembre 2016
    Messages
    383
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 28
    Localisation : Belgique

    Informations professionnelles :
    Activité : Full Stack (web) developer
    Secteur : Transports

    Informations forums :
    Inscription : Décembre 2016
    Messages : 383
    Points : 367
    Points
    367
    Par défaut
    Citation Envoyé par wiwaxia Voir le message
    Désolé, je n'avais pas vu qu'il s'agissait de proximité géométrique, caractérisée par la distance euclidienne séparant des coins supérieurs gauches.

    Il y a un bloc brun (Couleur1, coordonnées X1, Y1) et (Len) blocs rouges (Couleur2) listées dans Points. Il suffit de trouver la valeur minimale de (D2).

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
     X2:= Sqr(Xmax); Y2:=Sqr(Ymax); D2m:= X2 + Y2;     // Valeur maximale de D2min - Diagonale de l'image rectangulaire 
     FOR i:= 0 TO (Len - 1) DO                         // Je suppose que la liste des (Len) csg commence à zéro ...
       BEGIN
         X2:= Sqr(Points[i].X - X1); Y2:= Sqr(Points[i].Y - Y1); s:= X2 + Y2;
         IF (D2m>s) THEN BEGIN
                           D2m:= s; k:= i          // Nouvelle valeur plus faible de D2min; enregistrement du rang du terme correspondant
                         END
       END;  
     Xm:= Point[k].X; Ym:= Points[k].Y
    On obtient à l'issue de l'exécution de ces instructions les coordonnées (Xm, Ym) du bloc le plus proche.
    Il est possible qu'une procédure ou fonction de SCAR Divi effectue tâche analogue.
    Un grand merci
    Voici ma fonction

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    function BloqueDe4x4(out x, y : Integer; couleur, couleurs, xs, ys, xe, ye : integer) : Boolean;
    var 
    	Points, Point : TPointArray;
    	Idx, Len, couleur2, couleur3, couleur4 : Integer;
    	P : TPoint;
    	x1, y1, x2, y2, D2m, i, s, k : Integer;
    begin
    	result := False;
    	if FindColorEx(Points, couleurs, xs, ys, xe, ye) then // retourne un tableau contenant toutes les coordonnées détectée de la couleur
    	begin
    		Len := Length(Points);
    		for idx := 0 to Len - 1 do
    		begin
    			P := Points[Idx];
    			// pas très utile à vérifier peut-etre?
    			//vu que quand on trouve la couleur le 2e pixel est obligatoirement de la même couleur
    			//couleur2 := GetColor(P.X + 1, P.Y);
    			couleur3 := GetColor(P.X, P.Y + 1);
    			couleur4 := GetColor(P.X + 1, P.Y + 1);
    			if{(couleur2 = couleurs) and} (couleur3 = couleurs) and (couleur4 = couleurs) then
    			begin
    				Inc(Idx); //On exclus diret le PX+1
    			end;
    		end;
    		//détecter lequel est le plus proche
    		FindColor(x1, y1, couleur, xs, ys, xe, ye);
    		X2:= Round(Sqr(Points[Len-1].x));
    		Y2:= Round(Sqr(Points[Len-1].y));
    		D2m:= X2 + Y2;					// Valeur maximale de D2min - Diagonale de l'image rectangulaire 
    		for i:= 0 to (Len - 1) do		// Je suppose que la liste des (Len) csg commence à zéro ...
    		begin
    			X2:= Round(Sqr(Points[i].X - X1)); Y2:= Round(Sqr(Points[i].Y - Y1)); s:= X2 + Y2;
    			IF (D2m>s) then
    			begin
    				D2m:= s;				// Nouvelle valeur plus faible de D2min;
    				k:= i;					//enregistrement du rang du terme correspondant
    			end;
    		end;
    		x := Points[k].X;
    		y := Points[k].Y;
    		result := True;
    	end;
    end;

    Petite question encore la ligne 17 pensez vous qu'elle est utile?
    et les lignes 27 et 28 est-ce mieux de limiter au cadre? ou à dernier point trouvé?

+ Répondre à la discussion
Cette discussion est résolue.
Page 1 sur 2 12 DernièreDernière

Discussions similaires

  1. [XL-2010] Détection du changement de couleur de remplissage
    Par kev59600 dans le forum Macros et VBA Excel
    Réponses: 5
    Dernier message: 26/04/2016, 17h15
  2. Réponses: 7
    Dernier message: 08/07/2014, 12h21
  3. Détection de tache de couleur et centre de gravité
    Par soybenito dans le forum OpenCV
    Réponses: 3
    Dernier message: 30/05/2009, 10h57
  4. Détection des tons "chair" (couleur "chair")
    Par guiyomh dans le forum C
    Réponses: 1
    Dernier message: 08/06/2008, 15h58
  5. détection zone pour changer couleur
    Par petunia28 dans le forum Général JavaScript
    Réponses: 3
    Dernier message: 11/05/2006, 17h13

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo