前言

  项目中需要将imx185出来的raw数据转成dng格式,一开始认为很简单的事情,后面才发现还是挺复杂的!!!首先考虑的是不写任何代码,直接用adobe提供的转换工具来转,结果发现,不仅是adobe的工具,网上能够找到的工具(所谓的raw转dng)都是针对各大厂商的raw,而不能支持最原始的bayer raw。于是又考虑了两种解决方式,第一种就是将bayer raw随便转换成某一个厂商的raw(CR2, CRW, DNG, MRW, NEF, ORF, RAF, DCR, ARW中的一种),然后用所谓的raw转dng工具再转dng,结果发现厂商的raw一般都是不开放的,网上虽然有一些逆向工程,但不完整,没办法,只好用第二种方案了。第二种方案是考虑基于adobe提供的dng_sdk开发一个bayer转dng的程序,但是这个工作量真的很大,首先得完全弄懂dng格式,其次,adobe的sdk没有任何文档(html文件夹下有点点,但那个没多大作用),网上也找到不任何关于该sdk的说明!没办法,只好边看dng_spec_1.4.0.0边一步步解决。幸运的时,偶然在论坛上发现了两个关于bayer转dng的讨论,根据他们的代码,实现了转换。

dng_sdk linux移植具体步骤

  adobe官方提供的dng_sdk只有windows和mac版本,而我用的是linux系统,所以得想办法将其移植到linux里去。网上有有两种方案可以参考,方案一,一步一步按照他说的移植就ok了,方案二,也是一步一步根据他里面的文档并结合dng_sdk文档来移植。两种方案我都有试过,都是可行的,下面我主要基于第二种方案来说说具体的实践过程。

安装依赖jpeg

在ubuntu下,要安装jpeg依赖很简单,一条命令搞定

sudo apt-get install cmake libjpeg8-dev uuid-dev

安装依赖xmp sdk

下载xmp_sdk

wget http://download.macromedia.com/pub/developer/xmp/sdk/XMP-Toolkit-SDK-CC-201306.zip
unzip XMP-Toolkit-SDK-CC-201306.zip
mv XMP-Toolkit-SDK-CC201306 xmp_sdk

然后根据xmp_sdk/third-party下各子目录里的ReadMe.txt安装其他一些依赖

zlib

cd xmp_sdk/third-party/zlib
wget http://zlib.net/zlib-1.2.8.tar.gz
tar xzf zlib-1.2.8.tar.gz
cp zlib-1.2.8/*.h zlib-1.2.8/*.c .

expat

cd xmp_sdk/third-party/expat
Download here the source at http://sourceforge.net/projects/expat/files/expat/2.1.0/expat-2.1.0.tar.gz/download.
tar xzf expat-2.1.0.tar.gz
cp -R expat-2.1.0/lib .

dng sdk编译

在xmp_sdk文件夹所在的目录下执行以下命令获取源码

git clone https://github.com/yanburman/dng_sdk.git

进入目录projects/linux/,执行make即可编译生成dng_validate,该工具用于校验dng文件,后面生成的文件可以通过该工具来检测。

bayer转dng编译

拷贝下面的代码并命名为bayer2dng.cpp,

#include <iostream>

#include "dng_color_space.h"
#include "dng_date_time.h"
#include "dng_exceptions.h"
#include "dng_file_stream.h"
#include "dng_globals.h"
#include "dng_host.h"
#include "dng_ifd.h"
#include "dng_image_writer.h"
#include "dng_info.h"
#include "dng_linearization_info.h"
#include "dng_mosaic_info.h"
#include "dng_negative.h"
#include "dng_preview.h"
#include "dng_render.h"
#include "dng_simple_image.h"
#include "dng_tag_codes.h"
#include "dng_tag_types.h"
#include "dng_tag_values.h"
#include "dng_xmp.h"
#include "dng_xmp_sdk.h"
#include "dng_camera_profile.h"
// --------------------------------------------------------------------------------
//
// MakeDNGSample
//
int main(int argc, char *argv[])
{
// Sample BAYER image at ISO100 and tEXP 1/10 on f/4.0 and focal length 10mm
std::string m_szInputFile = "pic6";
uint16 m_unISO = 100;
double m_dExposureTime = 0.1;
double m_dLensAperture = 4.0;
double m_dFocalLength = 10.0; // SETTINGS: 12-Bit RGGB BAYER PATTERN
uint8 m_unColorPlanes = 3;
uint8 m_unBitDepth = 12;
uint16 m_unBayerType = 1; // RGGB
uint32 m_ulWidth = 1920;
uint32 m_ulHeight = 1225;
uint32 m_ulBlackLevel = 200; // SETTINGS: Whitebalance D65, Orientation "normal"
dng_orientation m_oOrientation = dng_orientation::Normal();
dng_xy_coord m_oWhitebalanceDetectedXY = D65_xy_coord(); // SETTINGS: Names
std::string m_szMake = "My Company";
std::string m_szCameraModel = "My Camera";
std::string szProfileName = m_szCameraModel;
std::string szProfileCopyright = m_szMake; // Calculate bit limit
uint16 m_unBitLimit = 0x01 << m_unBitDepth; // Form output filenames
std::string szBaseFilename = "";
std::string m_szOutputFile = "";
std::string m_szRenderFile = "";
std::string m_szPathPrefixInput = "";
std::string m_szPathPrefixOutput = "";
std::string m_szPathPrefixProfiles = "";
size_t unIndex = m_szInputFile.find_last_of(".");
if (unIndex == std::string::npos)
{
szBaseFilename = m_szInputFile;
}
else
{
szBaseFilename = m_szInputFile.substr(0, unIndex);
}
m_szInputFile = m_szPathPrefixInput + m_szInputFile;
m_szOutputFile = m_szPathPrefixOutput + szBaseFilename + ".dng";
m_szRenderFile = m_szPathPrefixOutput + szBaseFilename + ".tiff"; // Create DNG
try
{
dng_host oDNGHost; // -------------------------------------------------------------
// Print settings
// ------------------------------------------------------------- printf("\n");
printf("===============================================================================\n");
printf("Simple DNG converter\n");
printf("===============================================================================\n\n");
printf("\n");
printf("BAYER:\n");
printf("%s\n", m_szInputFile.c_str()); printf("\nConverting...\n"); // -------------------------------------------------------------
// BAYER input file settings
// -------------------------------------------------------------
dng_file_stream oBayerStream(m_szInputFile.c_str());
//oBayerStream.SetLittleEndian(false); uint32 ullBayerSize = (uint32)oBayerStream.Length(); AutoPtr<dng_memory_block> oBayerData(oDNGHost.Allocate(ullBayerSize)); oBayerStream.SetReadPosition(0); oBayerStream.Get(oBayerData->Buffer(), ullBayerSize); // -------------------------------------------------------------
// DNG Host Settings
// ------------------------------------------------------------- // Set DNG version
// Remarks: Tag [DNGVersion] / [50706]
oDNGHost.SetSaveDNGVersion(dngVersion_SaveDefault); // Set DNG type to RAW DNG
// Remarks: Store Bayer CFA data and not already processed data
oDNGHost.SetSaveLinearDNG(false); // -------------------------------------------------------------
// DNG Image Settings
// ------------------------------------------------------------- dng_rect vImageBounds(m_ulHeight, m_ulWidth); AutoPtr<dng_image> oImage(oDNGHost.Make_dng_image(vImageBounds, m_unColorPlanes, ttShort)); dng_pixel_buffer oBuffer; oBuffer.fArea = vImageBounds;
oBuffer.fPlane = 0;
oBuffer.fPlanes = 1;
oBuffer.fRowStep = oBuffer.fPlanes * m_ulWidth;
oBuffer.fColStep = oBuffer.fPlanes;
oBuffer.fPlaneStep = 1;
oBuffer.fPixelType = ttShort;
oBuffer.fPixelSize = TagTypeSize(ttShort);
oBuffer.fData = oBayerData->Buffer(); oImage->Put(oBuffer); // -------------------------------------------------------------
// DNG Negative Settings
// ------------------------------------------------------------- AutoPtr<dng_negative> oNegative(oDNGHost.Make_dng_negative()); // Set camera model
// Remarks: Tag [UniqueCameraModel] / [50708]
oNegative->SetModelName(m_szCameraModel.c_str()); // Set localized camera model
// Remarks: Tag [UniqueCameraModel] / [50709]
oNegative->SetLocalName(m_szCameraModel.c_str()); // Set bayer pattern information
// Remarks: Tag [CFAPlaneColor] / [50710] and [CFALayout] / [50711]
oNegative->SetColorKeys(colorKeyRed, colorKeyGreen, colorKeyBlue); // Set bayer pattern information
// Remarks: Tag [CFAPlaneColor] / [50710] and [CFALayout] / [50711]
oNegative->SetBayerMosaic(m_unBayerType); // Set bayer pattern information
// Remarks: Tag [CFAPlaneColor] / [50710] and [CFALayout] / [50711]
oNegative->SetColorChannels(m_unColorPlanes); // Set linearization table
// Remarks: Tag [LinearizationTable] / [50712]
AutoPtr<dng_memory_block> oCurve(oDNGHost.Allocate(sizeof(uint16)*m_unBitLimit));
for ( int32 i=0; i<m_unBitLimit; i++ )
{
uint16 *pulItem = oCurve->Buffer_uint16() + i;
*pulItem = (uint16)(i);
}
oNegative->SetLinearization(oCurve); // Set black level to auto black level of sensor
// Remarks: Tag [BlackLevel] / [50714]
oNegative->SetBlackLevel(m_ulBlackLevel); // Set white level
// Remarks: Tag [WhiteLevel] / [50717]
oNegative->SetWhiteLevel(m_unBitLimit-1); // Set scale to square pixel
// Remarks: Tag [DefaultScale] / [50718]
oNegative->SetDefaultScale(dng_urational(1,1), dng_urational(1,1)); // Set scale to square pixel
// Remarks: Tag [BestQualityScale] / [50780]
oNegative->SetBestQualityScale(dng_urational(1,1)); // Set pixel area
// Remarks: Tag [DefaultCropOrigin] / [50719]
oNegative->SetDefaultCropOrigin(0, 0); // Set pixel area
// Remarks: Tag [DefaultCropSize] / [50720]
oNegative->SetDefaultCropSize(m_ulWidth, m_ulHeight); // Set base orientation
// Remarks: See Restriction / Extension tags chapter
oNegative->SetBaseOrientation(m_oOrientation); // Set camera white XY coordinates
// Remarks: Tag [AsShotWhiteXY] / [50729]
oNegative->SetCameraWhiteXY(m_oWhitebalanceDetectedXY); // Set baseline exposure
// Remarks: Tag [BaselineExposure] / [50730]
oNegative->SetBaselineExposure(0); // Set if noise reduction is already applied on RAW data
// Remarks: Tag [NoiseReductionApplied] / [50935]
oNegative->SetNoiseReductionApplied(dng_urational(0,1)); // Set baseline sharpness
// Remarks: Tag [BaselineSharpness] / [50732]
oNegative->SetBaselineSharpness(1); // -------------------------------------------------------------
// DNG EXIF Settings
// ------------------------------------------------------------- dng_exif *poExif = oNegative->GetExif(); // Set Camera Make
// Remarks: Tag [Make] / [EXIF]
poExif->fMake.Set_ASCII(m_szMake.c_str()); // Set Camera Model
// Remarks: Tag [Model] / [EXIF]
poExif->fModel.Set_ASCII(m_szCameraModel.c_str()); // Set ISO speed
// Remarks: Tag [ISOSpeed] / [EXIF]
poExif->fISOSpeedRatings[0] = m_unISO;
poExif->fISOSpeedRatings[1] = 0;
poExif->fISOSpeedRatings[2] = 0; // Set WB mode
// Remarks: Tag [WhiteBalance] / [EXIF]
poExif->fWhiteBalance = 0; // Set metering mode
// Remarks: Tag [MeteringMode] / [EXIF]
poExif->fMeteringMode = 2; // Set metering mode
// Remarks: Tag [ExposureBiasValue] / [EXIF]
poExif->fExposureBiasValue = dng_srational(0, 0); // Set aperture value
// Remarks: Tag [ApertureValue] / [EXIF]
poExif->SetFNumber(m_dLensAperture); // Set exposure time
// Remarks: Tag [ExposureTime] / [EXIF]
poExif->SetExposureTime(m_dExposureTime); // Set focal length
// Remarks: Tag [FocalLength] / [EXIF]
poExif->fFocalLength.Set_real64(m_dFocalLength, 1000); // Set lens info
// Remarks: Tag [LensInfo] / [EXIF]
poExif->fLensInfo[0].Set_real64(m_dFocalLength, 10);
poExif->fLensInfo[1].Set_real64(m_dFocalLength, 10);
poExif->fLensInfo[2].Set_real64(m_dLensAperture, 10);
poExif->fLensInfo[3].Set_real64(m_dLensAperture, 10); // -------------------------------------------------------------
// DNG Profile Settings: Simple color calibration
// ------------------------------------------------------------- // Camera space RGB to XYZ matrix with D65 illumination
// Remarks: Derived from MATLAB using least square linear regression with
// MacBeth ColorChecker classic
dng_matrix_3by3 oCameraRGB_to_XYZ_D65 = dng_matrix_3by3( 2.3150, 0.0711, 0.1455,
0.9861, 0.7815,-0.2192,
0.2082,-0.3349, 1.6432 );
uint32 ulCalibrationIlluminant1 = lsD65; // Camera space RGB to XYZ matrix with StdA illumination
// Remarks: Derived from MATLAB using least square linear regression with
// MacBeth ColorChecker classic
dng_matrix_3by3 oCameraRGB_to_XYZ_A = dng_matrix_3by3( 1.6335, 0.4718,-0.0656,
0.5227, 1.0298,-0.3416,
0.0475,-0.2020 ,1.2522 ); uint32 ulCalibrationIlluminant2 = lsStandardLightA; AutoPtr<dng_camera_profile> oProfile(new dng_camera_profile); // Set first illuminant color calibration if available
if ( ulCalibrationIlluminant1!=0 )
{
// Set calibration illuminant 1
// Remarks: Tag [CalibrationIlluminant1] / [50778]
oProfile->SetCalibrationIlluminant1(ulCalibrationIlluminant1); // Set color matrix 1
// Remarks: Tag [ColorMatrix1] / [50721]
oProfile->SetColorMatrix1(Invert(oCameraRGB_to_XYZ_D65));
} // Set second illuminant color calibration if available
if ( ulCalibrationIlluminant2!=0 )
{
// Set calibration illuminant 2
// Remarks: Tag [CalibrationIlluminant2] / [50779]
oProfile->SetCalibrationIlluminant2(ulCalibrationIlluminant2); // Set color matrix 1
// Remarks: Tag [ColorMatrix2] / [50722]
oProfile->SetColorMatrix2(Invert(oCameraRGB_to_XYZ_A));
} // Set name of profile
// Remarks: Tag [ProfileName] / [50936]
oProfile->SetName(szProfileName.c_str()); // Set copyright of profile
// Remarks: Tag [ProfileCopyright] / [50942]
oProfile->SetCopyright(szProfileCopyright.c_str()); // Force flag read from DNG to make sure this profile will be embedded
oProfile->SetWasReadFromDNG(true); // Set policy for profile
// Remarks: Tag [ProfileEmbedPolicy] / [50941]
oProfile->SetEmbedPolicy(pepAllowCopying); // Add camera profile to negative
oNegative->AddProfile(oProfile); // -------------------------------------------------------------
// Write DNG file
// ------------------------------------------------------------- // Assign Raw image data.
oNegative->SetStage1Image(oImage); // Compute linearized and range mapped image
oNegative->BuildStage2Image(oDNGHost); // Compute demosaiced image (used by preview and thumbnail)
oNegative->BuildStage3Image(oDNGHost); // Update XMP / EXIF
oNegative->SynchronizeMetadata(); // Update IPTC
oNegative->RebuildIPTC(true); // Create stream writer for output file
dng_file_stream oDNGStream(m_szOutputFile.c_str(), true);
//oDNGStream.SetSwapBytes(1); // Write DNG file to disk
AutoPtr<dng_image_writer> oWriter(new dng_image_writer());
oWriter->WriteDNG(oDNGHost, oDNGStream, *oNegative.Get(), NULL, ccUncompressed); #if 0
// -------------------------------------------------------------
// Write TIFF file
// ------------------------------------------------------------- // Create stream writer for output file
dng_file_stream oTIFFStream(m_szRenderFile.c_str(), true); // Create render object
dng_render oRender (oDNGHost, *oNegative); // Set exposure compensation
oRender.SetExposure(0.0); // Create final image
AutoPtr<dng_image> oFinalImage; // Render image
oFinalImage.Reset (oRender.Render ());
oFinalImage->Rotate(oNegative->Orientation()); // Write TIFF file to disk
oWriter->WriteTIFF(oDNGHost, oTIFFStream, *oFinalImage.Get(), piRGB, ccUncompressed, oNegative.Get(), &oRender.FinalSpace ());
#endif } catch (const dng_exception &except)
{ return except.ErrorCode (); } catch (...)
{ return dng_error_unknown; } printf ("Conversion complete\n"); return 0;
}

保存,然后执行下面命令编译

g++ bayer2dng.cpp -I../../../xmp_sdk/public/include -I../../source libdng_sdk.a -ljpeg -lz -lpthread -ldl ../../../xmp_sdk/public/libraries/i80386linux_x64/release//staticXMPFiles.ar ../../../xmp_sdk/public/libraries/i80386linux_x64/release//staticXMPCore.ar -ldl -o bayer2dng

即可生成bayer转rgb的工具bayer2dng了。

总结

  上面的bayer2dng.cpp仅仅是将1920 1225分辨率 12bit RGGB格式的raw转为dng格式的文件,里面很多参数都需要根据实际情况调整,比如曝光时间、iso、光圈大小、焦距、线性表等等,所以继续研究dng格式是避免不了的_

引用

完!

2016年12月

bayer转dng实现过程记录的更多相关文章

  1. 升级Windows 10 正式版过程记录与经验

    升级Windows 10 正式版过程记录与经验 [多图预警]共50张,约4.6MB 系统概要: 预装Windows 8.1中文版 64位 C盘Users 文件夹已经挪动到D盘,并在原处建立了符号链接. ...

  2. 双系统Ubuntu分区扩容过程记录

    本人电脑上安装了Win10 + Ubuntu 12.04双系统.前段时间因为在Ubuntu上做项目要安装一个比较大的软件,导致Ubuntu根分区的空间不够了.于是,从硬盘又分出来一部分空间,分给Ubu ...

  3. CentOS 5.5 下安装Countly Web Server过程记录

    CentOS 5.5 下安装Countly Web Server过程记录 1. 系统更新与中文语言包安装 2. 基本环境配置: 2.1. NodeJS安装 依赖项安装 yum -y install g ...

  4. linux-i386(ubuntu)下编译安装gsoap_2.8.17过程记录

    过程记录 :  1.下载gsoap_2.8.17.zip 并 解压 : $unzip gsoap_2.8.17.zip     2.进入解压后的目录gsoap-2.8   3.自动配置编译环境:  $ ...

  5. 【转】android 最新 NDK r8 在window下开发环境搭建 安装配置与使用 详细图文讲解,完整实际配置过程记录(原创)

    原文网址:http://www.cnblogs.com/zdz8207/archive/2012/11/27/android-ndk-install.html android 最新 NDK r8 在w ...

  6. 升级到 ExtJS 5的过程记录

    升级到 ExtJS 5的过程记录   最近为公司的一个项目创建了一个 ExtJS 5 的分支,顺便记录一下升级到 ExtJS 5 所遇到的问题以及填掉的坑.由于 Sencha Cmd 的 sencha ...

  7. Ubuntu14.04 Tomcat 安装过程记录

    Ubuntu14.04 Tomcat 安装过程记录 检查java的版本 zhousp@ubuntu:~$ sudo java -version [sudo] password for zhousp: ...

  8. mercurial(Hg) Server 搭建 过程记录

    mercurial(Hg) Server 搭建 过程记录 1.  环境说明 只是测试搭建,环境为本机开发环境:win 8.1 + IIS8.5 软件准备: 2.  软件安装 先安装Python2.7, ...

  9. xp硬盘安装Fedora14 过程记录及心得体会(fedora14 live版本680M 和fedora14 DVD版本3.2G的选择)

    这次电脑奔溃了,奇怪的是直接ghost覆盖c盘竟然不中.之前电脑上硬盘安装的fedora14操作系统,也是双系统.不知道是不是这个问题,记得同学说过,在硬盘装fedora之后,要手动修改c盘隐藏的那个 ...

随机推荐

  1. ZooKeeper完全分布式安装与配置

    Apache ZooKeeper是一个为分布式应用所设计开源协调服务,其设计目是为了减轻分布式应用程序所承担的协调任务.可以为用户提供同步.配置管理.分组和命名服务. 1.环境说明 在三台装有cent ...

  2. winform自动最大化(在不同分辨率情况下)

    load函数末尾加: System.Drawing.Rectangle rec = Screen.GetWorkingArea(this); int SH = rec.Height; int SW = ...

  3. java计算两个日期之间的相隔天数

    [原创] 之前在很多竞赛的题目中有这样饿一类题,计算给定两个日期之间的相隔天数,或者很多类似的题目,都是需要转化到这个问题上时,之前用c++写的时候思想是这样的,一个结构体,包括年月日,还有一个计算下 ...

  4. Linux建立FTP服务器

    http://blog.chinaunix.net/uid-20541719-id-1931116.html http://www.cnblogs.com/hnrainll/archive/2011/ ...

  5. 深入理解Java Web——Servlet

    1.概述 狭义上看,是java的一个接口. 广义上看,任何直接或间接实现了Servlet接口的类. 2.核心对象 下面就是Servlet接口的内容: public abstract interface ...

  6. 一个flink作业的调优

    最近接手了一个flink作业,另外一个同事断断续续有的没的写了半年的,不着急,也一直没上线,最近突然要上线,扔给我,要调通上线. 现状是: 1.代码跑不动,资源给的不少,但是就是频繁反压. 2.che ...

  7. 【python】python各种类型转换-int,str,char,float,ord,hex,oct等

    [python] int(x [,base ])         将x转换为一个整数 long(x [,base ])        将x转换为一个长整数 float(x )             ...

  8. 【bzoj1465/bzoj1045】糖果传递 数论

    题目描述 老师准备了一堆糖果, 恰好n个小朋友可以分到数目一样多的糖果. 老师要n个小朋友去拿糖果, 然后围着圆桌坐好, 第1个小朋友的左边是第n个小朋友, 其他第i个小朋友左边是第i-1个小朋友. ...

  9. WebSocket添加事件监听器(6)

    WebSocket编程遵循异步编程模型;打开socket后,只需要等待事件发生,而不需要主动向服务器轮询,所以需要在WebSocket对象中添加回调函数来监听事件. WebSocket对象有三个事件: ...

  10. P4016 负载平衡问题

    题目描述 G 公司有 n 个沿铁路运输线环形排列的仓库,每个仓库存储的货物数量不等.如何用最少搬运量可以使 n个仓库的库存数量相同.搬运货物时,只能在相邻的仓库之间搬运. 输入输出格式 输入格式: 文 ...