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

VB.NET Discussion :

Non fonctionnement de la fonction GetPixel lors de la publication d'un projet


Sujet :

VB.NET

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Homme Profil pro
    Astronome amateur
    Inscrit en
    Juillet 2016
    Messages
    63
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haut Rhin (Alsace)

    Informations professionnelles :
    Activité : Astronome amateur
    Secteur : Industrie

    Informations forums :
    Inscription : Juillet 2016
    Messages : 63
    Par défaut Non fonctionnement de la fonction GetPixel lors de la publication d'un projet
    Bonjour

    Encore un problème lié à la publication de mon projet (analyse d'images astronomiques).

    J'ai un form dans lequel j'ai une picturebox qui me permet de visualiser une image. Sur cette image, lorsque je balade mon pointeur de souris, j'ai une indication en temps réel des composantes RVB du pixel sur lequel se situe le pointeur (voir copie d'écran).

    Lorsque je clique sur une étoile ou très proche, j'ai une première phase d'analyse de la zone qui me permet de trouver précisément le centre de l'étoile. Au final, j'ai une courbe de luminosité de l'étoile qui se trace, avec une coupe horizontale (courbe jaune) et une coupe verticale (courbe verte).

    Nom : Ecran couleur pixel.jpg
Affichages : 418
Taille : 75,6 Ko

    J'utilise un bout de code récupéré sur le net et qui me permet de déterminer les valeurs RVB du pixel survolé. J'utilise également cette même fonction pour déterminer le centre de l'étoile et établir la courbe de luminosité de l'étoile pointée.

    Voici le code que j'utilise :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    Private Declare Function GetPixel Lib "gdi32" Alias "GetPixel" (ByVal hdc As Int32, ByVal x As Int32, ByVal y As Int32) As Int32
     
    Dim win, rgb, hdc As Int32
    Dim g As Graphics = Graphics.FromHwnd(New IntPtr(win))
    hdc = g.GetHdc.ToInt32
    rgb = GetPixel(hdc, COORD_X, COORD_Y)
    PRed = rgb And &HFF
    PGreen = (rgb And &HFF00) / 256
    PBlue = (rgb And &HFF0000) / 65536
    Bref, dans mon projet, tout fonctionne parfaitement.

    Souhaitant utiliser ce programme sur d'autres ordinateurs, j'ai publié mon projet. Et là, patatra, la fonction ne marche pratiquement plus. En clair, j'ai essayé sur 4 autres ordinateurs et un seul fonctionne ! Sur tous les autres, la valeur de n'importe quel pixel est à &HFFFFFF et donc, tout le processus est un échec.

    J'ai vérifié que la gdi32.dll est bien présente sur les ordinateurs de test.

    J'ai passé des heures de recherche sur le ne, en vain.

    Une bonne âme aurait-elle une solution pour mon problème ?

    Merci à vous.

  2. #2
    Expert confirmé

    Avatar de François DORIN
    Homme Profil pro
    Consultant informatique
    Inscrit en
    Juillet 2016
    Messages
    2 761
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France, Charente Maritime (Poitou Charente)

    Informations professionnelles :
    Activité : Consultant informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2016
    Messages : 2 761
    Billets dans le blog
    21
    Par défaut
    Bonjour,

    Petite vérification à faire : quelle est l'architecture sur les PC où le programme marche ? Et ne marche pas ? 32bits ? Ou 64 bits ?

    Je pose la question car le type IntPtr représente un pointeur dont la taille dépend de l'architecture. Or, GetHdc retourne un IntPtr, sur lequel tu appelles toujours ToInt32 quelque soit l'architecture. Donc si mon diagnostique est bon, ton programme fonctionne correctement sur une architecture 32 bits, mais te renvoie une valeur erronée sur une architecture 64 bits (car convertir un pointeur 64 bits sur un entier 32 bits à de grande chance de te retourner une valeur erronée).

    Pour avoir une version qui fonctionne quelque soit l'architecture, voici ce que je ferais :
    • je modifierai le type du paramètre hdc de la fonction GetPixel. Utilse IntPtr au lieu de Int32
    • je supprimerai l'appel à ToInt32 pour utiliser directement le retour de la méthode GetHDC (qui est de type IntPtr)

  3. #3
    Membre averti
    Homme Profil pro
    Astronome amateur
    Inscrit en
    Juillet 2016
    Messages
    63
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haut Rhin (Alsace)

    Informations professionnelles :
    Activité : Astronome amateur
    Secteur : Industrie

    Informations forums :
    Inscription : Juillet 2016
    Messages : 63
    Par défaut
    Bonsoir François.

    L'ordi sur lequel j'ai développé mon projet est sous Win10 64 bits et tout fonctionne sans problème.
    Les 2 autres ordinateurs sur lesquels j'ai des problème sont sous seven 64 bits.

    Concernant le problème de getPixel, j'ai créé un petit projet avec une image sur laquelle j'utilise le GtPixel. A force de parcourir le net, j'ai trouvé une syntaxe très légèrement différente de celle que j'utilise. A priori, sur ce petit projet, ça fonctionne sur l'ordi Win10 et sur un des ordi avec seven. Je n'ai pas essayé le 3ème.

    Une fois que j'intègre ce code à jour dans mon projet principal, ça ne marche que partiellement. La valeur RGB des pixels s'affiche correctement sur une partie de l'image et sur le reste, j'ai une valeur de 255 sur chacune des composante, même sur du noir.

    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
        Dim rgb As Int32
        Dim hdc As IntPtr
     
      Using g As Graphics = Graphics.FromHwnd(PictureBox1.Handle)
                hdc = g.GetHdc
                rgb = GetPixel(hdc, X_Pointeur, Y_Pointeur)
                PRed = rgb And &HFF
                PGreen = (rgb And &HFF00) / 256
                PBlue = (rgb And &HFF0000) / 65536
                LBL_RVB.Text = Hex(rgb)
                LBL_Rouge.Text = PRed
                LBL_Vert.Text = PGreen
                LBL_Bleu.Text = PBlue
                ' LBL_hdc.Text = Hex(hdc)
                g.ReleaseHdc(hdc)
    End Using
    Je vais poursuivre les essais demain pour essayer de trouver ce qui cloche.

  4. #4
    Membre chevronné Avatar de electroremy
    Homme Profil pro
    Ingénieur sécurité
    Inscrit en
    Juin 2007
    Messages
    1 002
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France, Doubs (Franche Comté)

    Informations professionnelles :
    Activité : Ingénieur sécurité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2007
    Messages : 1 002
    Par défaut
    Bonjour,

    je travaille sur des images BMP mais en les traitant comme un tableau d'octets

    en fait je ne charge même pas les images dans des picture box, je lit les fichiers, et, au fil de l'eau, je créé un tableau d'octets

    on peut faire tous les tests qu'on veut, de façon très rapide, en utilisation des fonctions alignées sur 4 octets, ou des fonctions rapides comme << ou >> au lieu de divisions

    Une solution serait de ne pas utiliser GetPixel mais de travailler "en binaire" sur les données de l'images dans le .bitmap de ton image.

    En gros dans la RAM de l'ordi ton image est un tableau d'octet au format bitmap - attention selon le nombre de couleurs de l'affichage (32 bits, 24 bits, 16 bits...) la fonction GetPixel ne sera pas identique !

    Cette façon de travailler "en binaire" sera bien plus rapide que de faire de nombreux GetPixels si tu dois faire un traitement sur un gros morceau de l'image ou surtout l'image entière

    Pour faire simple, ton image est une liste des octets R, V, B de tous les pixels, de gauche à droite, chaque ligne l'une après l'autre

    Il faut faire un calcul pour retrouver, à partir des coordonnées X et Y, le n° de l'octet

    Attention il y a un piège, une ligne sera toujours composée d'un nombre d'octets égal à un multiple de 4 (donc il y a "un bourrage" de 0 non significatifs à la fin de la ligne.

    Attention également sur les ordinateurs l'axe Y est "inversé" par rapport à un repère scientifique XY orthonormé

    A bientôt

  5. #5
    Expert confirmé

    Avatar de François DORIN
    Homme Profil pro
    Consultant informatique
    Inscrit en
    Juillet 2016
    Messages
    2 761
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France, Charente Maritime (Poitou Charente)

    Informations professionnelles :
    Activité : Consultant informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2016
    Messages : 2 761
    Billets dans le blog
    21
    Par défaut
    Comment est déclarée ta fonction GetPixel ?

  6. #6
    Membre averti
    Homme Profil pro
    Astronome amateur
    Inscrit en
    Juillet 2016
    Messages
    63
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haut Rhin (Alsace)

    Informations professionnelles :
    Activité : Astronome amateur
    Secteur : Industrie

    Informations forums :
    Inscription : Juillet 2016
    Messages : 63
    Par défaut
    Bonjour electroremy

    Pour moi, il est impératif de visualiser l'image à l'écran car c'est une photo où se trouvent des étoiles (je fais de l'astronomie !). L'objectif de cette visualisation est de choisir une des étoiles présentes de manière à pouvoir faire la netteté de l'image, en manuel ou en automatique.

    La courbe qui résulte du traitement traduit la mise au point. Plus la courbe est étroite et haute, meilleure est la mise au point.

    Lorsque je clique sur une étoile (ou très proche de l'étoile), je prends un carré de 20x20pixels. J'analyse chaque pixel (400) dans le but de déterminer le centroïde de l'étoile, c'est à dire le centre ou les pixels sont les plus lumineux. J'utilise donc la fonction GetPixel (400 fois). Une fois que les coordonnées X et Y du centre de l'étoile sont déterminées, je fais une analyse de 20 pixels (10 de part et d'autre du centre) en horizontal puis la même chose en vertical. Là aussi, c'est le GetPixel qui permet de récupérer les valeurs et tracé la courbe.

    Une fois l'étoile "verrouillée", on déplace progressivement le dispositif de mise au point qui est motorisé et piloté directement par mon projet pour trouver le meilleur réglage.

    Par contre, je retiens ton idée de traitement en "aveugle" car l'idéal serait de pouvoir traiter plusieurs étoiles de manière à avoir une moyenne (ou les extrêmes) et là, les rapidité de calcul pourrait être appréciée.

  7. #7
    Membre chevronné Avatar de electroremy
    Homme Profil pro
    Ingénieur sécurité
    Inscrit en
    Juin 2007
    Messages
    1 002
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France, Doubs (Franche Comté)

    Informations professionnelles :
    Activité : Ingénieur sécurité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2007
    Messages : 1 002
    Par défaut
    Que l'image soit affichée ou non le principe du calcul sans passer par GetPixel est le même, et sera plus rapide

    Ton logiciel est raccordé à un reflex ou une caméra couplée sur un télescope avec monture motorisée ?

    Si oui, et si ta focale est longue, la rotation de la terre se voit à l’œil nu, il faut déplacer le télescope en temps réel

    Avec mon reflex APS-C et un objectif à mirroir de 500 mm (focale équivalente 24-36 de 750mm) je me suis amusé à photographier la dernière éclipse de lune

    Nom : RedMoonEclipse273.gif
Affichages : 348
Taille : 717,5 Ko

    http://electroremy.free.fr/28092015Eclipse

    Je devais réorienter mon appareil toutes les deux minutes

    De même regardes du côté du traitement du signal et des FFT en 2D il y a des choses très utiles

    Notamment cherche du côté de l'auto-correlation, c'est ce qu'il te faut pour caler une image sur une autre, ou une image sur une "carte" avec la position désirée des étoiles.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. [Débutant] Curseur perso absent lors de la publication d'un projet
    Par Discret68 dans le forum VB.NET
    Réponses: 28
    Dernier message: 07/04/2017, 20h42
  2. Erreur lors de la publication d'un projet web
    Par soso78 dans le forum Débuter
    Réponses: 1
    Dernier message: 31/07/2009, 13h56
  3. [PHP-JS] Formulaire non trouvé dans une fonction
    Par philippe30 dans le forum Langage
    Réponses: 4
    Dernier message: 11/12/2005, 21h53
  4. [CSS] non-fonctionnement de background-image
    Par Henri dans le forum Mise en page CSS
    Réponses: 1
    Dernier message: 16/09/2005, 20h06
  5. Critère non reconnu dans la fonction DCount
    Par Ps4 dans le forum Access
    Réponses: 7
    Dernier message: 20/06/2005, 09h02

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