banniere

Le portail francophone de la géomatique


Toujours pas inscrit ? Mot de passe oublié ?
Nom d'utilisateur    Mot de passe              Toujours pas inscrit ?   Mot de passe oublié ?

Annonce

Rencontres QGIS 2025

L'appel à participation est ouvert jusqu'au 19 janvier 2025!

#1 Tue 14 April 2009 18:55

nicolas.degarne
Participant occasionnel
Date d'inscription: 18 Apr 2008
Messages: 14

informations et aides sur GDAL

Bonjour à tous!

Je suis en train de travailler sur des images avec GDAL en c avec ubuntu...

Le but de mon programme est d'effectuer un traitement sur une fenertre 5x5 sur une image geotiff Size X: 17553 // Size Y: 15226 .

Le problème est que c'est tres long 310 secondes pour le moment, j'essaye avec 5 buffer de 5 bit que j'utilise pour créer mon masque avec une fonction  GDALRasterIO(  .

Existe-t-il des moyen pour allez plus vite...
             Utiliser des dalles de dataset pour accélérer le processus?
             Utiliser la fonction read/Write block?

Donc si quelqu'un utilise GDAL et a déjà été confronté à ces problèmes et qu'il peu m'aiguiller je vous en serait très reconnaissant.

Au faite je débute en GDAL et je ne suis pas un pro de programmation donc désolé si ma demande parait un peu bête

D'avance Merci

Bonne journée

NIcolas

Hors ligne

 

#2 Sun 26 April 2009 23:39

rouault
Participant assidu
Date d'inscription: 26 Apr 2009
Messages: 168

Re: informations et aides sur GDAL

Bonjour,

si j'ai bien compris pour chaque pixel de ton raster d'origine tu extrais une fenêtre de 5x5 pixels centrée sur lui ? Si c'est le cas, effectivement, un appel à GDALRasterIO() ayant un certain poids, cela pourrait expliquer une partie de la lenteur constatée (quoique ça ne me paraisse pas si long que ça finalement 310 secondes pour 267 millions de pixels). Une possibilité pour économiser des appels GDALRasterIO() serait d'extraire une fenêtre glissante de 5 lignes complètes. Tu peux te référer au code source de gdaldem (http://trac.osgeo.org/gdal/browser/trun … daldem.cpp) pour une illustration de cette technique pour un algorithme opérant sur des fenêtres de 3x3 pixels.

Even

Hors ligne

 

#3 Mon 27 April 2009 09:35

Yves
Membre du bureau
Lieu: Aix-les-Bains
Date d'inscription: 22 Mar 2006
Messages: 9869
Site web

Re: informations et aides sur GDAL

Merci Even pour ta réponse et bienvenu dans le forum GeoLibre smile

Y.


Yves Jacolin, bénévole de l'association GeoRezo.net, agit au nom et pour le compte de l'association - Partageons ce qui nous départage !!  - GeoRezo vous aide ? Aidez GeoRezo !

Hors ligne

 

#4 Mon 27 April 2009 14:43

nicolas.degarne
Participant occasionnel
Date d'inscription: 18 Apr 2008
Messages: 14

Re: informations et aides sur GDAL

Bonjour,

Merci de ta réponse, c'est en effet celle que j'avais utilisée et mon programme est passée de 300s à 18 s. Maintenant je m'attaque au problème des formats des données et c'est pas évident, étant tout un nouveau utilisateur de GDAL.Si Even tu as déjà utilisée le

Code:

 GDALCreate(...)

avec succès je serais heureux de savoir comment car j'ai utiliser la même technique que décrite dans le API tutoriel de Gdal mais je n'arrive pas a écrire dans l'image. Gdalinfos donne les bonnes informations de l'image mais quand j'essaye de l'ouvrir les données sembles ne pas être écrites .Si toi ou quelqu'un à une idée...

Encore merci

Nicolas

Hors ligne

 

#5 Mon 27 April 2009 19:43

rouault
Participant assidu
Date d'inscription: 26 Apr 2009
Messages: 168

Re: informations et aides sur GDAL

Cool pour l'amélioration notable des perfos.

Sinon, pour le problème avec GDALCreate(), je parierais sur un oubli d'un appel à GDALClose() à la fin de ton traitement. En effet, quand tu fais un GDALRasterIO(hBand, GF_Write, ...), les données ne sont pas directement écrites dans le fichier mais mises dans des blocs en cache mémoire. Au moment du GDALClose(), avant la destruction de l'objet C++ correspondant au Dataset, on procède à l'écriture des blocs modifiés encore en mémoire sur disque (cf GDALFlushCache()). De plus, pour certains drivers comme celui du GeoTIFF, des informations essentielles outre les blocs de données sont également écrites à la toute fin, ce qui fait qu'un oubli de GDALClose() peut faire en sorte que le fichier ne soit même pas lisible.

Si ce n'est pas ça la cause de ton problème, essaye d'isoler une séquence minimale où tu reproduis un problème et poste là ici.

Even

Hors ligne

 

#6 Mon 27 April 2009 20:25

nicolas.degarne
Participant occasionnel
Date d'inscription: 18 Apr 2008
Messages: 14

Re: informations et aides sur GDAL

Merci pour les conseil mais je pense avoir bien fermer mon image...

Code:

              //Free memory
        for( iwin = 0; iwin < winsize; iwin++)
        {
            CPLFree(hScanBloc1[iwin]);
        }
        GDALClose( hDataset );
        GDALClose( hDatasetOut );
        CPLFree(hScanBlocOut);
            GDALDestroyDriverManager();

Mon problème, c'est que je n'ai pas, du moins je n'ai pas d'erreur de compilation. J'ai suivi les différentes applications du tutoriel. J'ai essayé de "caster" mes données mais je ne comprend pas forcement les différents aspects à prendre en compte pour la réalisation de mon programme. Mais je trouve étrange qu'il n'alloues pas de mémoire, en effet la procédure GDALCreateCopy alloue de la mémoire mais la procédure GDALCreate( n'en alloue pas et la commande Used cache reste a 0;

   

Code:

    OutputFile = argv[2];
    if( OutputFile == NULL )
            Usage();
    else
        fprintf(stderr,"\nOutputfile : %s \n", argv[2]);

    const char *pszFormat = "GTiff";
    char **papszMetadata;
 



    GDALDriverH hDriver = GDALGetDriverByName( pszFormat );
    if( hDriver == NULL )
        exit( 1 );

    papszMetadata = GDALGetMetadata( hDriver, NULL );
    if( CSLFetchBoolean( papszMetadata, GDAL_DCAP_CREATE, FALSE ) )
        printf( "Driver %s supports Create() method.\n", pszFormat );
    if( CSLFetchBoolean( papszMetadata, GDAL_DCAP_CREATECOPY, FALSE ) )
        printf( "Driver %s supports CreateCopy() method.\n", pszFormat );

    char **papszOptions2 = NULL;

    //hDatasetOut = GDALCreateCopy( hDriver, OutputFile, hDataset, FALSE,NULL, NULL, NULL );
    hDatasetOut = GDALCreate( hDriver, OutputFile, nXSize, nYSize, 1, GDT_UInt16, NULL );
    if(hDatasetOut == NULL)
        exit(EXIT_FAILURE);


    double adfGeoTransform[6] ;
    CPLErr ertr;
    ertr=GDALGetGeoTransform( hDataset,adfGeoTransform);
    GDALSetGeoTransform( hDatasetOut, adfGeoTransform );
    
    const char *pszSRS_WKT = NULL;
    pszSRS_WKT= GDALGetProjectionRef(hDataset);
    GDALSetProjection( hDatasetOut, pszSRS_WKT);


    if( hDatasetOut == NULL )
    {
        fprintf( stderr, "GDALOpen 'out' failed - %d\n%s\n",CPLGetLastErrorNo(), CPLGetLastErrorMsg() );
          GDALDestroyDriverManager();
    Usage();
    }


     //Show picture out  informations
     nXSizeOut = GDALGetRasterXSize( hDatasetOut );
     nYSizeOut = GDALGetRasterYSize( hDatasetOut );
     nBandOut  = GDALGetRasterCount( hDatasetOut );

     fprintf( stderr, "Size X: %i \nSize Y: %i \nBand: %i \n", nXSizeOut, nYSizeOut, nBandOut);

J'ai mis le code que j'utilise pour créer mon image de sortie...

Si tu trouve quelque chose...

Encore merci pour tes conseils

Nicolas

Hors ligne

 

#7 Mon 27 April 2009 21:34

rouault
Participant assidu
Date d'inscription: 26 Apr 2009
Messages: 168

Re: informations et aides sur GDAL

Tu essayes de faire quoi exactement ? parce que GDALCreate() et GDALCreateCopy() font des choses complètement différentes.

- GDALCreateCopy() duplique un dataset déjà existant en un nouveau, avec les mêmes données de pixel, géoréférencement, etc... Tu as juste besoin de faire un GDALClose() juste après et voilou.
- GDALCreate() crée un nouveau dataset complètement vierge. Tout reste à faire après : les appels GDALSetGeoTransform(), GDALSetProjection(), GDALRasterIO(hBand, GF_Write, etc...), ...

Ne te base pas sur le fait que GDAL alloue des buffers internes. A la limite il pourrait ne pas en allouer du tout et écrire/lire directement les fichiers sans cache mémoire. C'est un détail d'implémentation interne à GDAL. Après un appel à GDALCreate(), il est normal que GDALGetCacheUsed() te renvoie 0 car on n'a pas besoin d'allouer de mémoire alors que rien n'a été fait (it's not a bug, it's a feature ;-)). Justement l'intérêt de GDAL est de pouvoir manipuler des fichiers énoooormes avec très peu de RAM. Le cache interne à GDAL est juste là pour "lisser" un peu les perfos en lecture en écriture.

Sinon, ton extrait de code est correct, mais ne m'éclaire pas vraiment sur tes intentions. J'ai l'impression que tu as "zappé" la partie la plus intéressante entre tes 2 extraits de code. Je me demande ce que tu fais dans ton "cast". Passes-tu bien un tableau de "short" à GDALRasterIO() ?

Voilà un exemple de code qui écrit une ligne entière avec la valeur 0, la suivante avec 1, etc...

Code:

#include "gdal.h"

int main(int argc, char* argv[])
{
    GDALAllRegister();

    int nXSize = 20;
    int nYSize = 20;
    GDALDatasetH ds = GDALCreate(GDALGetDriverByName("GTiff"), "test.tif", nXSize, nYSize, 1, GDT_Int16, NULL);
    GDALRasterBandH hBand = GDALGetRasterBand(ds, 1);

    int i, j;
    short* data = (short*)malloc(sizeof(short) * nXSize);
    for(j=0;j<nYSize;j++)
    {
        for(i=0;i<nXSize;i++)
            data[i] = j;

        GDALRasterIO( hBand, GF_Write, 0, j, nXSize, 1,
                            data, nXSize, 1, GDT_Int16, 0, 0 );
    }
    free(data);

    GDALClose(ds);
    return 0;
}

Hors ligne

 

#8 Mon 04 May 2009 18:34

nicolas.degarne
Participant occasionnel
Date d'inscription: 18 Apr 2008
Messages: 14

Re: informations et aides sur GDAL

Merci de tes aides Even,

Je comprend mieux le fonctionnement de GDAL Create maintenant  en faite mes problèmes venaient, je pense, du faite que lors de mon calcul je n'utilisais pas tous les pixels. En initialisant tout les pixels mon programme marche et affiche les resultats que je veux je te remercie encore pour toutes tes aides qui m'ont été d'une grande utilités.

Bonne journée

Nicolas

Hors ligne

 

Pied de page des forums

Powered by FluxBB