7
votes

Comment puis-je simplement charger un TIFF Greyscale dans Libtiff et obtenir une gamme d'intensités de pixels?

J'essaie de comprendre des images de plus, et j'ai beaucoup de problèmes. À partir de Matlab, j'ai de l'expérience dans l'utilisation d'Imread ("Test.tif ') et obtenez une belle matrice de lignes par rapport aux colonnes, où vous avez l'intensité de chaque pixel en tant qu'oeur entier. Ainsi, une image 720 x 250 donnera une matrice de 720 x 250, où chaque cellule contient l'intensité du pixel, sur une échelle de 0 à 255 (selon le type de données). Donc, 0 était noir, 255 était blanc.

C'était si simple et fait tellement de sens. Maintenant, je tente d'utiliser libtiff et je me débats vraiment. Je veux faire la même chose - accédez à ces pixels, et je ne peux tout simplement pas l'obtenir. P>

J'ai le code suivant: P>

int main(int argc, char *argv[]){
  TIFF* tif = TIFFOpen( argv[1], "r");
    FILE *fp = fopen("test2.txt", "w+");

  if (tif) {
      int * buf;
      tstrip_t strip;
      uint32* bc;
      uint32 stripsize;
  TIFFGetField( tif, TIFFTAG_STRIPBYTECOUNTS, &bc);
  stripsize = bc[0];
  buf   = _TIFFmalloc(stripsize);
  for(strip = 0; strip < TIFFNumberOfStrips(tif); strip++ ) {
      if( bc[strip] > stripsize) {
          buf = _TIFFrealloc(buf, bc[strip]);
          stripsize = bc[strip];
      }
      TIFFReadRawStrip(tif, strip, buf, bc[strip]);
  }
  int i;
  for (i=0; i<stripsize; i++) {
      if ( i % 960 ==0 )
          fprintf(fp, "\n");
      fprintf(fp,"%d ",  buf[i]);
  }
  _TIFFfree(buf);
  TIFFClose(tif);
  }
  exit(0);
}


2 commentaires

Je n'ai jamais utilisé libtiff, mais on dirait que vous lisez les données d'image brute. Le format de fichier TIFF peut contenir des données d'image brute mais aussi des formats comprimés. Donc, peut-être que les données sont toujours compressées.


Commencez par faire attention à la valeur de retour de ces fonctions. Vous n'avez aucune idée de savoir si la fonction a échoué ou non.


3 Réponses :


7
votes

Je pense que vous devriez lire Utilisation de l'article de bibliothèque TIFF . Il contient suffisamment d'informations pour commencer avec Libtiff.

Voici quelques codes pour lire les langues d'image et les valeurs d'impression de chaque échantillon. P>

main()
{
    TIFF* tif = TIFFOpen("myfile.tif", "r");
    if (tif) {
        uint32 imagelength;
        tsize_t scanline;
        tdata_t buf;
        uint32 row;
        uint32 col;

        TIFFGetField(tif, TIFFTAG_IMAGELENGTH, &imagelength);
        scanline = TIFFScanlineSize(tif);
        buf = _TIFFmalloc(scanline);
        for (row = 0; row < imagelength; row++)
        {
            TIFFReadScanline(tif, buf, row);
            for (col = 0; col < scanline; col++)
                printf("%d ", buf[col]);

            printf("\n");
        }
        _TIFFfree(buf);
        TIFFClose(tif);
    }
}


3 commentaires

Erreur: Trop peu d'arguments pour fonctionner 'tiffreadscanline'


@Eds. Veuillez définir la valeur par défaut pour la dernière action pour une fonction C. Également ouvert dans une coquille la page man: $ homme tiffreadscanline


@Malat: Je me souviens de laisser un commentaire ici un moment de retour, mais cela semble être parti maintenant. Quoi qu'il en soit ... Bobrovsky utilise C ++ ici et l'OP utilise C. Je suppose que je n'étais pas clair sur cela dans mon commentaire maintenant inexistant. Voici la déclaration si c_plusplus || __cplusplus est défini: extern int tiffreadCanline (TIFF * TIF, VOID * buf, ligne UINT32, échantillon UINT16 = 0);



3
votes

Concernant cet article, je pense que ce sera préférable d'utiliser une approche TIFFRGBAIMAGE, car comme il s'est avéré que le fichier TIFF pourrait être l'un des formats différents: carrelage, scanline basé sur la ligne et orienté en bande. Voici un exemple du même article.

TIFF* tif = TIFFOpen(argv[1], "r");
if (tif) {
    uint32 w, h;
    size_t npixels;
    uint32* raster;

    TIFFGetField(tif, TIFFTAG_IMAGEWIDTH, &w);
    TIFFGetField(tif, TIFFTAG_IMAGELENGTH, &h);
    npixels = w * h;
    raster = (uint32*) _TIFFmalloc(npixels * sizeof (uint32));
    if (raster != NULL) {
        if (TIFFReadRGBAImage(tif, w, h, raster, 0)) {
            ...process raster data...
        }
        _TIFFfree(raster);
    }
    TIFFClose(tif);
}


0 commentaires

2
votes

raster est un tableau UINT32 (valeur maximale = 0xFFFFFFFF) Mais vous essayez de lire un tableau 16 bits (valeur maximale 0xFFFF). Vous rencontrez des problèmes de conversion de 32 bits à 16 bits. La lecture de la méthode de numérisation est la meilleure façon de le faire. De cette façon, vous pouvez convertir le vide * buf en uint16 * et accéder aux valeurs de pixels.

#include <stdio.h>
#include <stdlib.h>
#include <iostream>
#include <inttypes.h>
#include "tiffio.h"


using namespace std;


void printArray(uint16 * array, uint16 width);
int main()
{


    TIFF* tif = TIFFOpen("16bit_grayscale_image.tif", "r");
     if (tif) {
    uint32 imagelength,height;
    tdata_t buf;
    uint32 row;
    uint32 config;

    TIFFGetField(tif, TIFFTAG_IMAGELENGTH, &imagelength);
     TIFFGetField(tif, TIFFTAG_IMAGELENGTH, &height);
    TIFFGetField(tif, TIFFTAG_PLANARCONFIG, &config);
    buf = _TIFFmalloc(TIFFScanlineSize(tif));


        uint16 s, nsamples;
        uint16* data;
        TIFFGetField(tif, TIFFTAG_SAMPLESPERPIXEL, &nsamples);
        for (s = 0; s < nsamples; s++)
        {
            for (row = 0; row < imagelength; row++)
                {
                TIFFReadScanline(tif, buf, row, s);
                data=(uint16*)buf;
                printArray(data,imagelength);
                }
                // printArray(data,imagelength,height);
        }


    _TIFFfree(buf);
    TIFFClose(tif);
    }
    exit(0);
}



void printArray(uint16 * array, uint16 width)
{
    uint32 i;
    for (i=0;i<width;i++)
    {
        printf("%u ", array[i]);
    }
        printf("\n");


}


0 commentaires