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

Python Discussion :

Calcul aire polygone - lecture image


Sujet :

Python

  1. #1
    Candidat au Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Décembre 2021
    Messages
    4
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 24
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Décembre 2021
    Messages : 4
    Par défaut Calcul aire polygone - lecture image
    Bonjour à toutes et à tous,

    J'aurais besoin d’une petite aide pour mon projet. Nous devons réfléchir sur une thématique. Mon projet porte sur la mise en place de panneaux solaires autour de l’aéroport de Carcassonne afin de voir s’il est possible de l’alimenter.

    Pour vous donner un peu de contexte, mon groupe et moi avons récupéré les coordonnées (long/lat) de chaque zone rouge (ce sont les zones interdites, ie les habitations) et je dois maintenant calculer la densité des panneaux solaires de chaque secteur (j’appelle secteur les anneaux de rayon 0.2).

    Je n’arrive pas à implémenter un code qui me permette de calculer l’aire que représente chaque zone rouge dans les anneaux de rayon 0.2. Le but est de calculer la densité de zone blanche dans un anneau. Je ferais seulement 1 – densité_zones_rouges pour avoir celle de la zone blanche.

    Par exemple, si nous prenons l’anneau 5, je veux exprimer la densité de zone blanche que représenterait ces panneaux.
    Je connais les sommets de chaque zone (coordonnées long/lat).
    Je suis capable de calculer l’aire de chaque zone rouge grâce à la formule de lacet.

    Mais je ne vois pas comment faire avoir l’aire dans l’anneau x.

    Nom : Capture d’écran 2021-12-20 à 14.20.09.png
Affichages : 1023
Taille : 123,9 Ko

    On m'a suggéré de lire l'image pixel par pixel puis de vérifier si x^2 + x^2 est supérieur ou inférieur à mon rayon.
    Ca pourrait marcher d'après vous ?
    Si oui, je n'ai jamais vraiment manipulé des images avec python :/
    Pourrie-vous m'aider ?

    Merci d'avance à vous,
    Je vous souhaite de bonnes fêtes

  2. #2
    Expert éminent
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 676
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : Architecte technique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2008
    Messages : 21 676
    Par défaut
    Salut,

    Citation Envoyé par MachineV5 Voir le message
    On m'a suggéré de lire l'image pixel par pixel puis de vérifier si x^2 + x^2 est supérieur ou inférieur à mon rayon.
    Ca pourrait marcher d'après vous ?
    Une image est juste un tableau à 2 dimensions que l'on va peut être transformer en array numpy suivant les calculs à faire dessus.
    Reste l'algorithme (les calculs à faire): il y a la rubrique algorithmique (et un forum traitement d'images) pour çà.

    - W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

  3. #3
    Membre prolifique
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 799
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 799
    Billets dans le blog
    1
    Par défaut
    Salut
    Citation Envoyé par MachineV5 Voir le message
    On m'a suggéré de lire l'image pixel par pixel puis de vérifier si x^2 + x^2 est supérieur ou inférieur à mon rayon.
    Ca pourrait marcher d'après vous ?
    Si oui, je n'ai jamais vraiment manipulé des images avec python :/
    Pourrie-vous m'aider ?
    C'est plus des maths que du Python ça. Déjà pour x²+y² supérieur ou inférieur au rayon oui c'est la formule du cercle en général (enfin sauf que le rayon est en réalité au carré => x²+y²=r²). Donc si x²+y²>rA² et x²+y²<rB² alors ça veut dire que le point(X, Y) se trouve dans la zone entre rA et rB.
    Mais personnellement je ne partirais pas sur la lecture d'image. L'image c'est une transcription visuelle (et déformée par cause de perte due aux arrondis) des valeurs que tu as déjà, à savoir les coordonnées des zones. Tu sembles débuter en informatique donc tu n'as pas encore les réflexes mais il faut savoir que quand on a les données de bases, on travaille directement dessus car on a les bonnes valeurs et non pas des valeurs dégradées par des transformations successives. Si je te demande de calculer 1/3*3 tu ne calcules pas 0.3*3, tu simplifies directement en supprimant la division et la multiplication.
    Donc tu as des cercles de rayon divers, et les coordonnées des zones. On peut vérifier si lesdites coordonnées sont ou ne sont pas entre deux rayons. Calculer les équations de droite (AB), (BC), (CD) et (DA) puis faire circuler un point imaginaire sur chaque droite et noter quand le point entre ou sort de la zone pour en extraire les coordonnées des points d'intersection, coordonnées qui forment donc une région dont on peut ensuite calculer la surface. Bon c'est pas aisé (faut travailler super rigoureusement, bien penser ses fonctions et surtout les tester de façon individuelle voir si elle donne le bon résultat) mais ce n'est pas insurmontable...
    Mon Tutoriel sur la programmation «Python»
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
    Et on poste ses codes entre balises [code] et [/code]

  4. #4
    Candidat au Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Décembre 2021
    Messages
    4
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 24
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Décembre 2021
    Messages : 4
    Par défaut
    Citation Envoyé par Sve@r Voir le message
    On peut vérifier si lesdites coordonnées sont ou ne sont pas entre deux rayons. Calculer les équations de droite (AB), (BC), (CD) et (DA) puis faire circuler un point imaginaire sur chaque droite et noter quand le point entre ou sort de la zone pour en extraire les coordonnées des points d'intersection, coordonnées qui forment donc une région dont on peut ensuite calculer la surface. Bon c'est pas aisé (faut travailler super rigoureusement, bien penser ses fonctions et surtout les tester de façon individuelle voir si elle donne le bon résultat) mais ce n'est pas insurmontable...
    Merci pour vos réponses respectives !
    En effet je ne suis pas vraiment un expert de la programmation ^^'
    J'aurais cependant une question pour toi Sve@r :

    Nom : Capture d’écran 2021-12-20 à 16.43.28.png
Affichages : 950
Taille : 137,9 Ko

    Si j'ai bien compris je dois faire parcourir un point sur ces droites de couleur cyan et à chaque fois qu'elle "touche" le cercle de rayon r, elle sauvegarde le point. Puis je calcule l'aire de du polygone compris dans l'anneau lié ?

    J'ai écrit ça pour le moment mais lorsque je parcours ma liste de points, comment faire pour avoir la droite (AD) je serais out of index non ?

    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
    def calcul_fonction(x,pointA, pointB):
        """Fonction qui permet de calculer l'équation entre deux objets de la classe Point"""
        coeff_directeur = (pointB.lat - pointA.lat) / (pointB.long-pointA.long)
        ordonnée_origine = pointA.lat - coeff_directeur * pointA.long
        return coeff_directeur * x + ordonnée_origine
     
    def calcul_density_secteur(secteur):
        P = secteur.points_zone
        for i in range(len(P)):
            if P[i].long < P[i+1].long:
                for j in range(P[i].long, P[i+1].long):
                    calcul_fonction(j,P[i],P[i+1])
                    ...
            else: 
                for j in range(P[i+1],P[i]):
                    calcul_fonction(j,P[i],P[i+1])
                    ...

    Voici mes classes pour Secteur et Point :

    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
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    class Point():
        def __init__(self,long,lat):
            self.long = long 
            self.lat = lat
            self.r = None
            self.theta = None
            self.convert_to_polar()
     
        def __repr__(self):
            return f'Point(r={self.r}, theta={self.theta})'
     
     
        def convert_to_polar(self):
            long_ref = REFERENCE[0]
            lat_ref = REFERENCE[1]
     
            self.r = np.sqrt((float(self.long)-long_ref)**2+(float(self.lat)-lat_ref)**2) 
            if self.lat > lat_ref:
                if self.long > long_ref:
                    self.theta = np.rad2deg(m.atan((float(self.long) - long_ref)/(float(self.lat) - lat_ref)))
                else: 
                    self.theta = np.rad2deg(m.atan(abs((float(self.lat) - lat_ref)/(float(self.long) - long_ref)))) + 270
            else:
                if self.long > long_ref:
                    self.theta = np.rad2deg(m.atan(abs((float(self.lat) - lat_ref)/(float(self.long) - long_ref)))) + 90
                else:
                    self.theta = np.rad2deg(m.atan((float(self.long) - long_ref)/(float(self.lat) - lat_ref))) + 180
     
    class Secteur():
        def __init__(self,numero, liste):
            self.numero = numero
            self.points_zone= liste
     
        def __repr__(self):
            return f'Zone(#zone={self.numero} ,Nb_Points:={len(self.points_zone)}, Liste_Points={self.points_zone})'
     
        def calcul_aire_secteur(self):
            corners = self.points_secteur
            n = len(corners)
            aire = 0.0
            for i in range(n):
                j = (i + 1) % n
                aire += corners[i].long * corners[j].lat
                aire -= corners[j].long * corners[i].lat
            aire = abs(aire) / 2.0
            return aire
     
    def creation_secteurs(fichier):
        liste_zones=lecture_fichier(fichier)
        S = []
        for zone,liste_points in liste_zones.items():
            S.append(Secteur(zone,liste_points))
        return S
    Merci encore pour votre aide !

  5. #5
    Invité
    Invité(e)
    Par défaut
    Salut !

    Juste une idée farfelue si l'approximation est tolérée et si j'ai bien compris la demande :
    - Tracer automatiquement un cercle noir de rayon X
    - Compter le nombre de pixels blancs et rouges
    - Tracer automatiquement un cercle noir de rayon X + 1
    - Compter à nouveau le nombre de pixels blancs et rouges
    - Déduire les nombres pour avoir le nombre de pixels de tel ou tel couleur dans l'anneau [X : X+1]
    - Calculer l'air total de l'anneau
    - Faire un rapport en croix pour obtenir l'air de tel ou tel couleur
    Nom : dev-pixel.gif
Affichages : 960
Taille : 56,9 Ko


    Pour tracer un cercle noir au milieu d'une image :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    from PIL import Image, ImageDraw
     
    im = Image.open("1.jpg")
     
    x, y =  im.size
    eX, eY = 60, 60 #Size of Bounding Box for ellipse
     
    bbox =  (x/2 - eX/2, y/2 - eY/2, x/2 + eX/2, y/2 + eY/2)
    draw = ImageDraw.Draw(im)
    draw.ellipse(bbox, fill=0)
    del draw
     
    im.save("output.png")
    im.show()
    Nom : 1.jpg
Affichages : 930
Taille : 657 octets Nom : output.png
Affichages : 947
Taille : 886 octets

    Pour obtenir le nombre de pixels :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    from PIL import Image
    im = Image.open('output.png')
     
    black = 0
    green = 0
     
    for pixel in im.getdata():
        if pixel == (0, 128, 1): # if your image is RGB (if RGBA, (0, 0, 0, 255) or so
            green += 1
        elif pixel == (0, 0, 0):
            black += 1
        else:
            print('Other color :', pixel)
    print('black=' + str(black)+', green='+str(green))
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    black=2909, green=57091
    PS : Il n'est pas nécessaire de sauvegarder les images, tu peux combiner les 2 codes... et compléter avec ce qui manque !
    Dernière modification par Invité ; 20/12/2021 à 18h49.

  6. #6
    Membre prolifique
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 799
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 799
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par MachineV5 Voir le message
    Si j'ai bien compris je dois faire parcourir un point sur ces droites de couleur cyan et à chaque fois qu'elle "touche" le cercle de rayon r, elle sauvegarde le point. Puis je calcule l'aire de du polygone compris dans l'anneau lié ?
    Exactement. En plus, pour le calcul d'aire d'une surface fermée, il existe un algorithme pour çà: l'algorithme de remplissage.

    Citation Envoyé par MachineV5 Voir le message
    J'ai écrit ça pour le moment mais lorsque je parcours ma liste de points, comment faire pour avoir la droite (AD) je serais out of index non ?
    Ben... imaginons A(1, 2) et B(9, 4). La droite a pour équation y=(x+7)/4. Ensuite pour avoir tous les points entre A et B, suffit de faire varier x de 1 à 9 et calculer les y correspondants...

    Citation Envoyé par LeNarvalo Voir le message
    Juste une idée farfelue si l'approximation est tolérée et si j'ai bien compris la demande :
    - Tracer automatiquement un cercle noir de rayon X
    - Compter le nombre de pixels blancs et rouges
    - Tracer automatiquement un cercle noir de rayon X + 1
    - Compter à nouveau le nombre de pixels blancs et rouges
    - Déduire les nombres pour avoir le nombre de pixels de tel ou tel couleur dans le rayon [X : X+1]
    C'est un peu son idée première: compter le nombre de pixels rouges et faire une proportion par rapport à la surface totale. Mais "compter" les pixels ça reste soit une analyse d'image, soit des calculs sur les valeurs numériques correspondant à l'image (un tableau de points comme mentionné par wiztricks). Mais ton exemple est pas mal
    Mon Tutoriel sur la programmation «Python»
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
    Et on poste ses codes entre balises [code] et [/code]

  7. #7
    Candidat au Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Décembre 2021
    Messages
    4
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 24
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Décembre 2021
    Messages : 4
    Par défaut
    Citation Envoyé par LeNarvalo Voir le message
    Salut !

    Juste une idée farfelue si l'approximation est tolérée et si j'ai bien compris la demande :
    - Tracer automatiquement un cercle noir de rayon X
    - Compter le nombre de pixels blancs et rouges
    - Tracer automatiquement un cercle noir de rayon X + 1
    - Compter à nouveau le nombre de pixels blancs et rouges
    - Déduire les nombres pour avoir le nombre de pixels de tel ou tel couleur dans l'anneau [X : X+1]
    - Calculer l'air total de l'anneau
    - Faire un rapport en croix pour obtenir l'air de tel ou tel couleur

    Wow merci pour ta réponse LeNarvalo !!

    Petite question :

    Est-il possible de créer deux cercles vides et contour plein et donc obtenir cela :

    Nom : Capture d’écran 2021-12-20 à 21.00.20.png
Affichages : 908
Taille : 52,0 Ko

    Cela serait beaucoup plus simple pour obtenir ce que je veux ! Je ne sais pas si cela est possible

    En tout cas merci pour le temps que vous prenez ^^

  8. #8
    Membre prolifique
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 799
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 799
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par MachineV5 Voir le message
    Est-il possible de créer deux cercles vides et contour plein et donc obtenir cela :
    Ben... entre 0 et r1 tout noir, entre r1 et r2 tout blanc, et entre r2 et rMax tout noir...
    Mon Tutoriel sur la programmation «Python»
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
    Et on poste ses codes entre balises [code] et [/code]

  9. #9
    Candidat au Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Décembre 2021
    Messages
    4
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 24
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Décembre 2021
    Messages : 4
    Par défaut
    Citation Envoyé par Sve@r Voir le message
    Ben... entre 0 et r1 tout noir, entre r1 et r2 tout blanc, et entre r2 et rMax tout noir...
    Si je fais cela, je n'aurais pas le rouge ... :/

    Nom : Capture d’écran 2021-12-20 à 23.07.14.png
Affichages : 911
Taille : 15,9 Ko

    Je n'arrive pas à centrer l'ellipse aussi ...

    J'ai exactement pris le même code :

    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
    def cercle_noir():
        im = Image.open("output.png")
     
        x, y =  im.size
        eX, eY = 18, 18 #Size of Bounding Box for ellipse
     
        bbox =  (x/2 - eX/2, y/2 - eY/2, x/2 + eX/2, y/2 + eY/2)
        draw = ImageDraw.Draw(im)
        draw.ellipse(bbox, fill=(0,0,0))
        del draw
     
        im.show()
        black = 0
        red = 0
     
        for pixel in im.getdata():
            if pixel == (255, 0, 0, 255): 
                red += 1
            elif pixel == (0, 0, 0, 255):
                black += 1
            else:
               print('Other color :', pixel)
        print('black=' + str(black)+', red='+str(red))

  10. #10
    Invité
    Invité(e)
    Par défaut
    Citation Envoyé par MachineV5 Voir le message
    Est-il possible de créer deux cercles vides et contour plein
    Oui mais avec PIL je crois que ce n'est pas simple lien... Le code qui nécessiterait le moins de ligne me paraît être celui consistant à créer deux cercles noirs de rayon x et x+1 respectivement comme je l'expliquais.

    Concernant le centrage de l'ellipse, essayes-ça :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    bbox =  (326 - eX/2, 326 - eY/2, 326 + eX/2, 326 + eY/2)
    Mettre en plein-écran :


    ^^

Discussions similaires

  1. Calcul de différence d'image
    Par Pouf842 dans le forum Traitement d'images
    Réponses: 8
    Dernier message: 23/01/2008, 16h22
  2. Calcul erreur entre deux images noir et blanc
    Par b4sols dans le forum Images
    Réponses: 1
    Dernier message: 22/03/2007, 08h59
  3. Calcul surface polygone/cercle
    Par wwave dans le forum Algorithmes et structures de données
    Réponses: 3
    Dernier message: 21/03/2007, 18h16
  4. Calcul du nombre d'images par seconde
    Par Mindiell dans le forum SDL
    Réponses: 5
    Dernier message: 19/03/2007, 22h12
  5. Réponses: 4
    Dernier message: 22/01/2006, 21h32

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