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

2D Java Discussion :

Récupérer une ligne ou une colonne le plus rapidement dans un BufferedImage


Sujet :

2D Java

  1. #1
    Modérateur
    Avatar de ToTo13
    Homme Profil pro
    Chercheur en informatique
    Inscrit en
    Janvier 2006
    Messages
    5 793
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : Etats-Unis

    Informations professionnelles :
    Activité : Chercheur en informatique
    Secteur : Santé

    Informations forums :
    Inscription : Janvier 2006
    Messages : 5 793
    Points : 9 860
    Points
    9 860
    Par défaut Récupérer une ligne ou une colonne le plus rapidement dans un BufferedImage
    Bonjour,

    ben voilà tout est dans le titre.
    Je voudrai récupérer au plus vite toutes les valeurs d'une ligne ou d'une colonne dans un BufferedImage.

    Je sais que l'on peut bien sûr faire une boucle et récupérer les valeurs via le Raster, mais c'est lent.
    Y a t-il plus rapide ?
    Du genre un pointeur vers les lignes et/ou les colonnes ?

    Merci par avance...

  2. #2
    Membre habitué
    Profil pro
    Inscrit en
    Mai 2005
    Messages
    155
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2005
    Messages : 155
    Points : 199
    Points
    199
    Par défaut
    je me demande
    getRgb(int x, int y)?
    est-ce aussi lent que passer par le raster?

    Personellement je pense pas que ce soit possible de faire plus rapide sur le cpu, il faudrait passer par du calcul sur gpu pour réaliser ton traitement sur le gpu.

  3. #3
    Expert éminent sénior
    Avatar de sinok
    Profil pro
    Inscrit en
    Août 2004
    Messages
    8 765
    Détails du profil
    Informations personnelles :
    Âge : 44
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Août 2004
    Messages : 8 765
    Points : 12 977
    Points
    12 977
    Par défaut
    Tu crées une seconde BufferdImage de la taille de la ligne/colonne que tu veux puis tu passe par une des méthodes drawImage qui va bien.
    A savoir celle ci:
    drawImage(Image img, int dx1, int dy1, int dx2, int dy2, int sx1, int sy1, int sx2, int sy2, ImageObserver observer)

  4. #4
    Modérateur
    Avatar de ToTo13
    Homme Profil pro
    Chercheur en informatique
    Inscrit en
    Janvier 2006
    Messages
    5 793
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : Etats-Unis

    Informations professionnelles :
    Activité : Chercheur en informatique
    Secteur : Santé

    Informations forums :
    Inscription : Janvier 2006
    Messages : 5 793
    Points : 9 860
    Points
    9 860
    Par défaut
    Bonjour,

    Citation Envoyé par sinok Voir le message
    Tu crées une seconde BufferdImage de la taille de la ligne/colonne que tu veux puis tu passe par une des méthodes drawImage qui va bien.
    A savoir celle ci:
    drawImage(Image img, int dx1, int dy1, int dx2, int dy2, int sx1, int sy1, int sx2, int sy2, ImageObserver observer)
    C'est ce genre de chose que je cherchais.
    Connais tu le principes qui se cache derrière ? Recopie mémoire directe telle un memcopy en C ?
    As tu une idée du gain de performance ?

  5. #5
    Rédacteur
    Avatar de pseudocode
    Homme Profil pro
    Architecte système
    Inscrit en
    Décembre 2006
    Messages
    10 062
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Architecte système
    Secteur : Industrie

    Informations forums :
    Inscription : Décembre 2006
    Messages : 10 062
    Points : 16 084
    Points
    16 084
    Par défaut
    Citation Envoyé par ToTo13 Voir le message
    Je sais que l'on peut bien sûr faire une boucle et récupérer les valeurs via le Raster, mais c'est lent.
    Y a t-il plus rapide ?
    Du genre un pointeur vers les lignes et/ou les colonnes ?
    Pour ce genre de chose, il faut accèder au DataBuffer. Il y a de grandes chances que ce soit une instance DataBufferByte.

    Code java : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    DataBufferByte db = (DataBufferByte) image.getRaster().getDataBuffer();
    byte[] bytes = db.getData();
    Le tableau bytes est un stockage linéaire des octets (gauche/droite, haut/bas).

    Pour une image RGB l'ordre des bandes est inversé je crois : {B1,G1,R1,B2,G2,R2,...}

    L'équivalent de

    int value = getSample(x, y, b)

    serait alors

    int value = (int) (bytes[3*(x+y*WIDTH)+(2-b)] & 0xFF);

  6. #6
    Expert éminent sénior
    Avatar de sinok
    Profil pro
    Inscrit en
    Août 2004
    Messages
    8 765
    Détails du profil
    Informations personnelles :
    Âge : 44
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Août 2004
    Messages : 8 765
    Points : 12 977
    Points
    12 977
    Par défaut
    De souvenir ces méthodes sont accélérées au niveau hardware, donc toutes les opérations sont réalisées au niveau de la CG. Tu gagneras encore plus de temps en utilisant des images compatibles. cf http://java.developpez.com/faq/gui/?...ompatibleImage

    Dès que tu touches au Raster tu perds tout ce que java peut apporter en accélération hardware. Donc l'appel au raster doit être évité autant que possible.


  7. #7
    Modérateur
    Avatar de ToTo13
    Homme Profil pro
    Chercheur en informatique
    Inscrit en
    Janvier 2006
    Messages
    5 793
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : Etats-Unis

    Informations professionnelles :
    Activité : Chercheur en informatique
    Secteur : Santé

    Informations forums :
    Inscription : Janvier 2006
    Messages : 5 793
    Points : 9 860
    Points
    9 860
    Par défaut
    Citation Envoyé par pseudocode Voir le message
    Pour ce genre de chose, il faut accèder au DataBuffer. Il y a de grandes chances que ce soit une instance DataBufferByte.

    Code java : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    DataBufferByte db = (DataBufferByte) image.getRaster().getDataBuffer();
    byte[] bytes = db.getData();
    Le tableau bytes est un stockage linéaire des octets (gauche/droite, haut/bas).

    Pour une image RGB l'ordre des bandes est inversé je crois : {B1,G1,R1,B2,G2,R2,...}
    L'équivalent de int value = getSample(x, y, b)
    serait alors
    int value = (int) (bytes[3*(x+y*WIDTH)+(2-b)] & 0xFF);
    Merci pour l'info, ça m'intéresse.
    Par contre je ne devrai pas avoir le souci de traiter des images couleurs dans un premier temps.



    Citation Envoyé par sinok Voir le message
    De souvenir ces méthodes sont accélérées au niveau hardware, donc toutes les opérations sont réalisées au niveau de la CG. Tu gagneras encore plus de temps en utilisant des images compatibles. cf http://java.developpez.com/faq/gui/?...ompatibleImage

    Dès que tu touches au Raster tu perds tout ce que java peut apporter en accélération hardware. Donc l'appel au raster doit être évité autant que possible.
    Je me doutais bien que le Raster était le mal en terme de performance.
    Je ne connaissais pas les ImageCompatible et ça m'intéresse.

    Je ferai un test entre les deux méthodes pour savoir celle qui marche le mieux, je donnerai les résultats et marquerai alors "Résolu".
    Il s'agit d'un traitement de Morphologie Mathématique très particulier (traitement d'images), donc beaucoup d'accès à faire en un minimum de temps, avec des recopies de lignes nécessaires (d'où ma question).

  8. #8
    Modérateur
    Avatar de ToTo13
    Homme Profil pro
    Chercheur en informatique
    Inscrit en
    Janvier 2006
    Messages
    5 793
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : Etats-Unis

    Informations professionnelles :
    Activité : Chercheur en informatique
    Secteur : Santé

    Informations forums :
    Inscription : Janvier 2006
    Messages : 5 793
    Points : 9 860
    Points
    9 860
    Par défaut
    Bonjour,

    je continue cette discussion, car j'ai un peu de temps pour concrétiser.

    En faisant cela, je récupère un pointeur sur mon tableau qui contient les données :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    byte[] bytes = db.getData();
    Mais dans ce que je veux faire au final, je dois faire une comparaison ultra-rapide entre les éléments de mon image, donc contenus dans mon tableau.
    Et c'est là que je pense avoir un souci : ce sont des byte !!! Et ce quelque soit les images hormis USHORT_GRAY.
    Donc un codage sur [-128, 127]. Donc il me faudra convertir toutes les valeurs pour pouvoir les comparer. Et je perdrai alors beaucoup de temps.

    Est ce qu'il y aurait un moyen de stocker (ou autre) directement un équivalent java des "unsigned byte" ?

    D'ailleurs comment sont codés les images USHORT_GRAY car il me semble qu'il n'existe aucun "unsigned" dans les types Java ?

  9. #9
    Rédacteur
    Avatar de pseudocode
    Homme Profil pro
    Architecte système
    Inscrit en
    Décembre 2006
    Messages
    10 062
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Architecte système
    Secteur : Industrie

    Informations forums :
    Inscription : Décembre 2006
    Messages : 10 062
    Points : 16 084
    Points
    16 084
    Par défaut
    Citation Envoyé par ToTo13 Voir le message
    Mais dans ce que je veux faire au final, je dois faire une comparaison ultra-rapide entre les éléments de mon image, donc contenus dans mon tableau.
    Code ton algo en C et fait un appel JNI

    Donc un codage sur [-128, 127]. Donc il me faudra convertir toutes les valeurs pour pouvoir les comparer.
    Pourquoi convertir les valeurs pour les comparer ? les données de référence ne sont pas des Bytes ?

  10. #10
    Modérateur
    Avatar de ToTo13
    Homme Profil pro
    Chercheur en informatique
    Inscrit en
    Janvier 2006
    Messages
    5 793
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : Etats-Unis

    Informations professionnelles :
    Activité : Chercheur en informatique
    Secteur : Santé

    Informations forums :
    Inscription : Janvier 2006
    Messages : 5 793
    Points : 9 860
    Points
    9 860
    Par défaut
    Citation Envoyé par pseudocode Voir le message
    Code ton algo en C et fait un appel JNI
    Je fais pas du Java pour revenir aux sources


    Citation Envoyé par pseudocode Voir le message
    Pourquoi convertir les valeurs pour les comparer ? les données de référence ne sont pas des Bytes ?
    Mmm... là il doit me manquer une information... :s

    Je travaille sur un tableau de byte (que je viens de récupérer comme marqué si dessus).
    Je souhaite comparer toutes les valeurs entre elles : savoir entre deux valeurs laquelle est la plus grande (resp. plus petite).
    Donc je fais habituellement un Math.max(v1,v2).
    Mais comme le codage est sur [-128,127], ce qui fait que (byte)255 aura une valeur négative et du coup il faudrait rétablir la valeur positive avant de faire la comparaison.
    A moins qu'il y ait une méthode qui permette de faire des comparaisons "intelligentes" de byte.

  11. #11
    Rédacteur
    Avatar de pseudocode
    Homme Profil pro
    Architecte système
    Inscrit en
    Décembre 2006
    Messages
    10 062
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Architecte système
    Secteur : Industrie

    Informations forums :
    Inscription : Décembre 2006
    Messages : 10 062
    Points : 16 084
    Points
    16 084
    Par défaut
    Citation Envoyé par ToTo13 Voir le message
    Je fais pas du Java pour revenir aux sources



    Mmm... là il doit me manquer une information... :s

    Je travaille sur un tableau de byte (que je viens de récupérer comme marqué si dessus).
    Je souhaite comparer toutes les valeurs entre elles : savoir entre deux valeurs laquelle est la plus grande (resp. plus petite).
    Donc je fais habituellement un Math.max(v1,v2).
    Mais comme le codage est sur [-128,127], ce qui fait que (byte)255 aura une valeur négative et du coup il faudrait rétablir la valeur positive avant de faire la comparaison.
    A moins qu'il y ait une méthode qui permette de faire des comparaisons "intelligentes" de byte.
    Ah ok. Bon, bah je ne vois pas de solution magique. Le plus simple c'est la conversion en int avant d'appeler math.max:

    byte b1,b2;

    Math.max(b1 & 0xFF , b2 & 0xFF)

  12. #12
    Modérateur
    Avatar de ToTo13
    Homme Profil pro
    Chercheur en informatique
    Inscrit en
    Janvier 2006
    Messages
    5 793
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : Etats-Unis

    Informations professionnelles :
    Activité : Chercheur en informatique
    Secteur : Santé

    Informations forums :
    Inscription : Janvier 2006
    Messages : 5 793
    Points : 9 860
    Points
    9 860
    Par défaut
    Citation Envoyé par pseudocode Voir le message
    Ah ok. Bon, bah je ne vois pas de solution magique. Le plus simple c'est la conversion en int avant d'appeler math.max:

    byte b1,b2;

    Math.max(b1 & 0xFF , b2 & 0xFF)
    D'ailleurs, qu'est ce qui est le plus rapide ?
    - Math.max(b1 & 0xFF , b2 & 0xFF)
    - Math.max(0<=b1?b1:256f+b1, 0<=b2?b2:256+b2)

  13. #13
    Rédacteur
    Avatar de pseudocode
    Homme Profil pro
    Architecte système
    Inscrit en
    Décembre 2006
    Messages
    10 062
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Architecte système
    Secteur : Industrie

    Informations forums :
    Inscription : Décembre 2006
    Messages : 10 062
    Points : 16 084
    Points
    16 084
    Par défaut
    Citation Envoyé par ToTo13 Voir le message
    D'ailleurs, qu'est ce qui est le plus rapide ?
    - Math.max(b1 & 0xFF , b2 & 0xFF)
    - Math.max(0<=b1?b1:256f+b1, 0<=b2?b2:256+b2)
    Sur ma machine :

    boucle de 1.000.000, c'est kif kif (15/16 ms)
    boucle de 1.000.000.000, la première méthode est 5 fois plus rapide (1500/8400 ms)

  14. #14
    Modérateur
    Avatar de ToTo13
    Homme Profil pro
    Chercheur en informatique
    Inscrit en
    Janvier 2006
    Messages
    5 793
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : Etats-Unis

    Informations professionnelles :
    Activité : Chercheur en informatique
    Secteur : Santé

    Informations forums :
    Inscription : Janvier 2006
    Messages : 5 793
    Points : 9 860
    Points
    9 860
    Par défaut
    Citation Envoyé par pseudocode Voir le message
    boucle de 1.000.000, c'est kif kif (15/16 ms)
    boucle de 1.000.000.000, la première méthode est 5 fois plus rapide (1500/8400 ms)
    Ok merci pour le test !
    J'étais en train de tester directement l'effet dans mon problème :cool:

Discussions similaires

  1. Réponses: 3
    Dernier message: 18/01/2015, 19h30
  2. Réponses: 3
    Dernier message: 23/10/2013, 14h52
  3. Réponses: 5
    Dernier message: 08/01/2013, 18h03
  4. Réponses: 2
    Dernier message: 18/11/2012, 12h25
  5. Récupérer les valeurs d'une ligne d'une datagrid (Silverlight)
    Par johnaliashead dans le forum Silverlight
    Réponses: 2
    Dernier message: 14/04/2010, 17h01

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