前言

  项目中需要将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. django中判断当前user具有是否有对模块的增删改查权限

    首先简单了解一下user的一些属性 User对象 User对象是认证系统的核心.用户对象通常用来代表网站的用户,并支持例如访问控制.注册用户.关联创建者和内容等.在Django认证框架中只有一个用户类 ...

  2. TensorFlow 调用预训练好的模型—— Python 实现

    1. 准备预训练好的模型 TensorFlow 预训练好的模型被保存为以下四个文件 data 文件是训练好的参数值,meta 文件是定义的神经网络图,checkpoint 文件是所有模型的保存路径,如 ...

  3. npm安装不成功的原因

    使用npm安装electron不成功的解决方法 使用npm安装electron不成功的解决方法 根据官网提供的electron的npm安装方法,使用下面的命令进行安装,结果不成功 npm instal ...

  4. Gitlab自动触发Jenkins构建项目

    Gitlab自动触发Jenkins构建项目 一.前提 Gitlab已安装配置好. Jenkins已安装Gitlab plugin. 二.配置jenkins中Job 1.勾选触发器下的gitlab触发器 ...

  5. gitbook.explore更新升级了, 不能再搜索了

    www.gitbook.com/explore 不再是一个索引页面 Can I browse existing projects on GitBook ? The new version of Git ...

  6. NO7——二分

    int binsearch(int *t,int k,int n) {//t为数组,k是要查找的数,n为长度,此为升序 ,high = n,mid; while(low<=high) { mid ...

  7. UVA 437 The Tower of Babylon(DAG上的动态规划)

    题目大意是根据所给的有无限多个的n种立方体,求其所堆砌成的塔最大高度. 方法1,建图求解,可以把问题转化成求DAG上的最长路问题 #include <cstdio> #include &l ...

  8. Qscintilla2编译使用

    Qscintilla2的下载地址: https://github.com/josephwilk/qscintilla https://riverbankcomputing.com/software/q ...

  9. JQuery实现的智能表单提示

    实现一个类似如此效果的表单验证:

  10. Android 实现异步加载图片

    麦洛开通博客以来,有一段时间没有更新博文了.主要是麦洛这段时间因项目开发实在太忙了.今天周六还在公司加班,苦逼程序猿都是这样生活的. 今天在做项目的时候,有一个实现异步加载图片的功能,虽然比较简单但还 ...