2011-03-29 8 views
5

Estoy tratando de entender las imágenes un poco más, y estoy teniendo un gran problema. A partir del uso de matlab, tengo experiencia en el uso de imread ('test.tif') y obtener una hermosa matriz de filas y columnas, donde tienes la intensidad de cada píxel como un número entero. Entonces, una imagen de 720 x 250 dará una matriz de 720 x 250, donde cada celda contiene la intensidad del píxel, en una escala de 0 a 255 (dependiendo del tipo de datos). Entonces, 0 era negro, 255 era blanco.¿Cómo puedo simplemente cargar un tiff de escala de grises en libtiff y obtener una matriz de intensidades de píxeles?

Era tan simple y tenía tanto sentido. Ahora estoy intentando usar libtiff, y realmente estoy luchando. Quiero hacer lo mismo: acceder a esos píxeles, y simplemente no puedo obtenerlo.

Tengo el siguiente código:

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); 
} 

pero me da resultados completamente sin sentido - sólo por completo hacia fuera wacked números. No hay nada como los números que veo cuando cargo la imagen en matlab.

¿Cómo puedo acceder a los valores de píxel y mirarlos?

Muchas gracias.

+0

Nunca utilicé libtiff, pero parece que está leyendo los datos brutos de la imagen. El formato de archivo Tiff puede contener datos de imágenes sin formato pero también formatos comprimidos. Entonces, tal vez los datos aún estén comprimidos. – Lucas

+1

Comience prestando atención al valor de retorno de estas funciones. No tienes idea si la función falló o no. –

Respuesta

6

Creo que deberías leer Using The TIFF Library article. Contiene suficiente información para comenzar con libtiff.

Aquí hay un código para leer las líneas de escaneo de imágenes y los valores de impresión de cada muestra.

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); 
    } 
} 
+1

error: muy pocos argumentos para funcionar 'TIFFReadScanline' – malat

+0

@EdS. Defina 'valor predeterminado para el último argumento' para una función C. También abra en un shell la página man: '$ man TIFFReadScanline' – malat

+0

@malat: Recuerdo haber dejado un comentario aquí hace un tiempo, pero parece que ya no está. De todos modos ... Bobrovsky está usando C++ aquí y el OP está utilizando C. Supongo que no estaba claro en mi comentario ahora inexistente. Aquí está la declaración si 'c_plusplus || __cplusplus' se define: 'extern int TIFFReadScanline (TIFF * tif, void * buf, uint32 fila, uint16 sample = 0);' –

1

Con respecto a este artículo, creo que va a ser mejor usar el enfoque TIFFRGBAImage, porque como se vio después archivo TIFF podría ser uno de los diferentes formatos: baldosas, basado en línea de escaneo y orientado de tira. Aquí hay un ejemplo del mismo artículo.

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); 
} 
2

trama es una matriz uint32 (valor máximo = 0xffffffff) pero usted está tratando de leer una matriz de 16 bits (valor máximo 0xffff). se encontrará con problemas de conversión de 32 bits a 16 bits. Leer el método de escaneo es la mejor manera de hacerlo. De esta forma puede convertir void * buf en uint16 * y acceder a los valores de píxel.

#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"); 


} 
Cuestiones relacionadas