如何简单地在 libtiff 中加载灰度 tiff 并获取像素强度数组?

发布于 2024-10-27 12:51:15 字数 1154 浏览 7 评论 0原文

我试图更多地理解图像,但遇到了很多麻烦。通过使用 matlab,我有使用 imread('test.tif') 的经验,并获得了一个漂亮的行与列矩阵,其中每个像素的强度为整数。因此,720 x 250 图像将给出 720 x 250 矩阵,其中每个单元格包含像素强度,范围为 0-255(取决于数据类型)。所以,0 是黑色,255 是白色。

它是如此简单,也如此有意义。现在我正在尝试使用 libtiff,但我真的很挣扎。我想做同样的事情——访问这些像素,但我就是无法得到它。

我有以下代码:

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

但我得到了完全没有意义的结果——只是完全扭曲的数字。与我在 matlab 中加载图像时看到的数字完全不同。

我怎样才能简单地访问像素值并查看它们?

非常感谢。

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 when I load the image in matlab.

How can I simply access the pixel values, and look at them?

Thanks so much.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

你另情深 2024-11-03 12:51:15

我认为您应该阅读使用 TIFF 库文章。它包含足够的信息来开始使用 libtiff。

下面是一些读取图像扫描线并打印每个样本值的代码。

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

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);
    }
}
皓月长歌 2024-11-03 12:51:15

关于本文,我认为使用 TIFFRGBAImage 方法会更好,因为事实证明 TIFF 文件可能是不同的格式之一:平铺、基于扫描线和面向条带。这是同一篇文章中的一个示例。

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

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);
}
瞳孔里扚悲伤 2024-11-03 12:51:15

raster 是一个 uint32 数组(最大值= 0xffffffff)
但您正在尝试读取 16 位数组(最大值 0xffff)。
您将遇到 32 位到 16 位转换的问题。
读取扫描线方法是更好的方法。
这样您就可以将 void* buf 转换为 uint16* 并访问像素值。

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


}

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


}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文