天天看点

使用Adobe dng SDK一步一步显示图像

作者:sinosun

dng格式是数码相机原始数据的公共存档格式,是Adob​e创建的一种开源RAW文件格式。DNG文件存储由各种相机型号(如哈苏、宾得和徕卡)捕获的未压缩图像数据。DNG文件可以使用多个图像查看软件打开,包括 Windows和macOS 中的内置照片应用程序。DNG下载地址为:Digital Negative (DNG), Adobe DNG Converter | Adobe Photoshop

dng_sdk附带一个dng_validate程序,可以打印所有的tag信息。当然也可以稍微修改做其它用途。

使用Adobe dng SDK一步一步显示图像

dng_validate命令行

使用-v参数,可以获取很多dng的tag信息,如下图

使用Adobe dng SDK一步一步显示图像
使用Adobe dng SDK一步一步显示图像

RAW格式是原始拜耳数据,我们是如何看到彩色的图像了,这里借用Adobe的dng sdk一步一步给大家做个演示。

其实下面的-1 -2 -3其实就是图片转换的3个步骤,下面我们一步一步的来学习。

使用Adobe dng SDK一步一步显示图像

第一步:从dng文件中把raw数据解析出来

首先-1,看看dng_sd帮助怎么说的,简单来说就是原始数据输出,啥都不干

The “-1” option causes the unprocessed raw image data to be written to the named output file. This applies only to the next input file after the switch.

其对应的dng_sdk源码为:

// Option to write stage 1 image.

		if (gDumpStage1.NotEmpty())
		{

			if (negative->Stage1Image())
			{

				dng_file_stream stream2(gDumpStage1.Get(), true);

				const dng_image& stage1 = *negative->Stage1Image();

				dng_image_writer writer;

				writer.WriteTIFF(host,
					stream2,
					stage1,
					stage1.Planes() >= 3 ? piRGB
					: piBlackIsZero);
			}
			gDumpStage1.Clear();
		}

		// Metadata.
		negative->SynchronizeMetadata();           

使用-1 参数就能保存我们的raw图像数据,可以用ps打开,这里就不演示了。

使用下面的代码也可以保存这个文件

char* p_stage1_buffer = new char[stage1.PixelSize() * stage1.Height() * stage1.Width()];
    if (p_stage1_buffer != nullptr)
    {
        dng_pixel_buffer stage1_pixel_buffer(stage1.Bounds(), 0, stage1.Planes(), stage1.PixelType(), pcPlanar, p_stage1_buffer);
        stage1.Get(stage1_pixel_buffer);
                
        FILE* stage1_f = fopen("stage1.raw", "w+b");
        if (stage1_f != nullptr)
        {
            fwrite(p_stage1_buffer, stage1.PixelSize(), stage1.Width() * stage1.Height(), stage1_f);
             fclose(stage1_f);
         }
         delete[] p_stage1_buffer;
    }           

第二步:黑电平校准

从第一步可知,这个raw是BGGR的拜耳格式,1个拜耳通道的black level 都是 528, white level = 4095。也就是说,这个raw的是12bit的,因此最大值为 (1<<12)-1 = 4095。

使用Adobe dng SDK一步一步显示图像

我们看下-2 帮助文档怎么解释的:

The “-2” option causes the image data after linearization and black/white level mapping to be written to the named output file. This applies only to the next input file after the switch.

下面是代码,首先根据pixel位置和拜耳格式,获取当前pixel是哪种类型,是R/G/G/B四种类型的哪一种,然后再分别减去对应的black level值;减完black level以后,值域范围变成了0~3839,我们需要把它映射回0~4095,因此,所有的pixel都乘上了一个global_gain值;

static void blc_correct(UINT16* buf, UINT32 width, UINT32 height, UINT16 white_level, BAYER_TYPE bayer, const UINT16 blc_vec[4])
{
    UINT32 global_gain = UINT32(white_level * 1024) / (white_level - blc_vec[0]);
    UINT32 size = width * height;
    for (UINT32 i = 0; i < height; i++)
    {
        for (UINT32 j = 0; j < width; j++)
        {
            PIXEL_TYPE type = get_pixel_type(j, i, bayer);
            UINT16 blc_value = blc_vec[type];
            INT32 temp = buf[i*width+j] - blc_value;
            if (temp < 0)
                temp = 0;
            else if (temp > white_level)
                temp = white_level;

            UINT32 out = ((UINT32)temp * global_gain + 512) >> 10;
            if (out < 0)
                out = 0;
            else if (out > white_level)
                out = white_level;
            buf[i*width + j] = (UINT16)out;
        }
    }
}           

-2 之后会得到一张处理完黑电平之后的一张图像。

使用Adobe dng SDK一步一步显示图像

第三步:插值,白平衡,gama校准

The “-3” option causes the image data after demosaic processing, but prior to color space conversion, noise reduction, sharpening, etc., to be written to the named output file. This applies only to the next input file after the switch.

继续阅读