I am trying to understand images some more, and I'm having a great deal of trouble. From using matlab, I have experience in using imread('test.tif'), and getting a beautiful matrix of rows vs. columns, where you have the intensity of each pixel as an integer. So, a 720 x 250 image will give a 720 x 250 matrix, where each cell contains the intensity of the pixel, on a scale from 0-255 (depending on the data type). So, 0 was black, 255 was white.
It was so simple and made so much sense. Now I am attempting to use libtiff, and I am really struggling. I want to do the same thing--access those pixels, and I just can't get it.
I have the following code:
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);
}
But I get completely meaningless results--just completely wacked out numbers. Nothing like the numbers I see whe开发者_开发技巧n I load the image in matlab.
How can I simply access the pixel values, and look at them?
Thanks so much.
I think you should read Using The TIFF Library article. It contains enough information to get started with libtiff.
Here is some code to read image scanlines and print values of each sample.
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);
}
}
Regarding this article, I think it'll be better to use TIFFRGBAImage approach, because as it turned out TIFF file could be one of different formats: tiled, scanline-based and strip-oriented. Here's an example from the same 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);
}
raster is a uint32 array (maximum value= 0xffffffff) but you are trying to read a 16-bit array (maximum value 0xffff). you will run into 32bit to 16bit conversion problems. Reading the scanline method is the better way to do it. This way you can convert the void* buf to uint16* and access the pixel values.
#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");
}
精彩评论