You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C++读取非标准12位深度TIFF图像的方案求助

读取12位单通道无压缩TIFF图像的问题

我最近在处理高速相机生成的12位单通道无压缩TIFF图像,测试OpenCV、libTIFF、TinyTIFF均失败,报错信息统一为“仅支持8、16、24或32位TIFF”。

我目前有两个思路:

  • 直接将文件作为二进制读取后处理,但不清楚具体实现方法
  • 使用ImageMagick的convert工具将通道深度转为16位,但需要处理数十万张图像,两次读写(转换+后处理)效率极低,因此不想采用该方案

复现错误的libTIFF示例代码

TIFF* tif = TIFFOpen(imageName.c_str(), "r");

// Create a matrix to hold the tif image in
Mat image;

// check the tif is open
if (tif) {
    do {
        unsigned int width, height;
        uint32* raster;

        // get the size of the tiff
        TIFFGetField(tif, TIFFTAG_IMAGEWIDTH, &width);
        TIFFGetField(tif, TIFFTAG_IMAGELENGTH, &height);

        uint npixels = width * height; // get the total number of pixels

        raster = (uint32*)_TIFFmalloc(npixels * sizeof(uint32)); // allocate temp memory (must use the tiff library malloc)
        if (raster == NULL) // check the raster's memory was allocaed
        {
            TIFFClose(tif);
            throw bad_alloc();
        }

        // Check the tif read to the raster correctly
        if (!TIFFReadRGBAImage(tif, width, height, raster, 0))
        {
            TIFFClose(tif);
            throw runtime_error("Could not read the TIF appropriately");
        }

        image = Mat(width, height, CV_8UC4); // create a new matrix of w x h with 8 bits per channel and 4 channels (RGBA)

        // iterate over all the pixels of the tif
        for (uint x = 0; x < width; x++)
            for (uint y = 0; y < height; y++)
            {
                uint32& TiffPixel = raster[y * width + x]; // read the current pixel of the TIF
                Vec4b& pixel = image.at<Vec4b>(Point(y, x)); // read the current pixel of the matrix
                pixel[0] = TIFFGetB(TiffPixel); // Set the pixel values as BGRA
                pixel[1] = TIFFGetG(TiffPixel);
                pixel[2] = TIFFGetR(TiffPixel);
                pixel[3] = TIFFGetA(TiffPixel);
            }

        _TIFFfree(raster); // release temp memory
        // Rotate the image 90 degrees couter clockwise
        image = image.t();
        flip(image, image, 0);
        imshow("TIF Image", image); // show the image
        waitKey(0); // wait for anykey before displaying next
    } while (TIFFReadDirectory(tif)); // get the next tif
    TIFFClose(tif); // close the tif file
}

补充信息(编辑1)

所有图像均来自同一款高速相机,位深度一致且未压缩。用tiffinfo工具查看任意一张图像的输出如下:

=== TIFF directory 0 ===
TIFF Directory at offset 0x22f5e (143198)
  Image Width: 258 Image Length: 370
  Bits/Sample: 12
  Compression Scheme: None
  Photometric Interpretation: min-is-black
  Orientation: row 0 top, col 0 lhs
  Samples/Pixel: 1
  Rows/Strip: 21
  Planar Configuration: single image plane

ImageMagick API尝试(编辑2)

我尝试用ImageMagick API读取图像,假设它支持任意位深度的TIFF,但调用read方法后得到的是零尺寸图像,未抛出异常,问题仍未解决:

// Create base image 
Image image;
Mat cvImage;
try{
    image.read(imageName);
    // Set the image type to TrueColor DirectClass representation.
    image.type(GrayscaleType);
    // Ensure that there is only one reference to underlying image 
    // If this is not done, then image pixels will not be modified.
    //image.modifyImage();

    // Allocate pixel view 
    Pixels view(image);

    // Set all pixels in region anchored at 38x36, with size 160x230 to green. 
    size_t columns = view.columns(); size_t rows = view.rows();

    cvImage = Mat(columns, rows, CV_8UC(1)); // create a new matrix of w x h with 8 bits per channel and 4 channels (RGBA)
    Quantum* pixels = view.get(0, 0, columns, rows);
    for (ssize_t row = 0; row < rows; ++row)
        for (ssize_t column = 0; column < columns; ++column)
        {
            uchar& pixel = cvImage.at<uchar>(cv::Point(column, row)); // read the current pixel of the matrix

            pixel = *pixels++; // Set the pixel values as BGRA
        }

    imshow("TIF Image", cvImage); // show the image
    cv::waitKey(0); // wait for anykey before displaying next
} catch (Magick::Exception& error_)
{
    cout << "Caught exception: " << error_.what() << endl;
} 

临时解决方案(编辑3)

目前使用以下命令批量转换格式,但希望找到更高效的直接读取方案:

mogrify -format png *.tif

内容的提问来源于stack exchange,提问作者Kbzon

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.24 10:33:19