使用 MATLAB 和 Dcraw 处理 RAW 图像文件

学期正在学习有关数字图像处理的课程,今天课堂讨论的时候,忽然回忆起去年的一门实验课的内容——分析相机成像的像质。我在那时写了一篇相关内容的总结,其中提到了一位学长所写的使用最为原始的方法对相机的RAW原始图像文件进行处理的文章,直到现在我才对其中的原理有了一定系统性的了解。于是,按照那篇文章的教程,我使用MATLAB和Dcraw对RAW文件进行了处理。

前言

使用MATLAB对RAW文件进行处理并从中提取出我们想要的图像信息,这是一种最彻底、最根本的获取相机传感器原始信息的方法,并且这些信息都是以数字的形式记录下来,可以很方便地在此基础上进行图像的存储、传输或者进一步操作。

Dcraw预处理

我们要把可执行文件放在C:\windows路径下,这样可以直接从运行(Win+R)中执行。在运行中输入cmd进入命令行窗口,这时已经可以直接调用Dcraw,或者输入dcraw查看相关的一些命令。

由于我们不准备用Dcraw对RAW文件做任何处理,只需要输入:

1
dcraw-4-T-D-vpathfilename

其中pathfilename为RAW图像文件的路径。这里的-T表示将图像以tiff格式导出,-D表示不对图像做任何的彩色插值和亮度调节,-v表示在Dcraw处理结束后在屏幕上显示相关信息,而-4等价于-6-W-g11,即表示导出的图像为16位(而不是常见的JPEG的8位)、不进行任何白平衡校正、不进行任何伽马校正。在一些需要获取拍照时白平衡设置的场合也可以使用-6-w-g11-T-D这样的参数组合,但这里我们使用-4-T-D就好。各参数的意义在官方文档页面中有详细的说明。

1

得到了tiff格式的图像如下图所示。这里可以看出得到的tiff图像是灰度图像,只记录了光强度的信息,不包含任何颜色信息。由于各个像素上记录的光强度是一个标量,这幅图像相当于一个m\timesnm×n的矩阵,其中mm和nn分别为CMOS纵向和横向的像素数。

我使用FastStoneImageViewer软件能够直接浏览RAW文件和tiff文件,对于RAW文件来说,虽然我们在图像查看器中能够看到图像,但软件中展示的图像只是嵌入在RAW文件中的经过一系列转码的缩略图而并非RAW本身。为了避免各种图像浏览软件不同的解码方式对预览图像造成的影响,下面都使用MATLAB中的imshow函数来浏览图像。

我们先在MATLAB中读取该图像,再进行后面的处理:

1
raw=double(imread(''));

线性处理

出于节省数据存储空间的目的,一些厂商的RAW文件并不完全与像素点上的照度呈线性关系,而是会在编码上做一些处理,比如非线性压缩等。不过这里我们不需要担心这个问题,因为之前在Dcraw中使用-4参数时就已经解决了这个问题。我们只要确保各个像素的数值是分布在14-bit(虽然Dcraw中的-4参数将图像设为16位,但其最大值仍然为2^{14}-1=16383214−1=16383)能够储存的范围之间即可,一般为0\sim163830∼16383,并将超出这个区间的数值给拉回区间中。再将这些数值归一化至0\sim10∼1区间中。

1234
black=2047;saturation=13584;lin_bayer=(raw-black)/(saturation-black);%归一化至[0,1]lin_bayer=max(0,min(lin_bayer,1));%确保没有大于1或小于0的数据

这里的black和saturation两个参数的数值需要对RAW文件通过dcraw-v-T命令查看,因为不同的厂家和不同的相机型号该数值都可能不同。

这一步我们得到的图像如下图所示。

白平衡校正

123
wb_multipliers=[2.639648,1,1.319336];%forparticularcondition,fromdcraw;mask=wbmask(size(lin_bayer,1),size(lin_bayer,2),wb_multipliers,'rggb');balanced_bayer=lin_bayer.*mask;

上面代码中的wbmask函数是根据实际拜耳滤镜的排列生成对应的掩板:

1234567891011128192021
functioncolormask=wbmask(m,n,wbmults,align)%COLORMASK=wbmask(M,N,WBMULTS,ALIGN)%Makesawhite-balancemultiplicativemaskforanimageofsizem-by-n%withRGBwhilebalancemultipliersWBMULTS=[R_scaleG_scaleB_scale].%ALIGNisstringindicatingBayerarrangement:'rggb','gbrg','grbg','bggr'colormask=wbmults(2)*ones(m,n);%Initializetoallgreenvalues;switchaligncase'rggb'colormask(1:2:,1:2:)=wbmults(1);colormask(2:2:,2:2:)=wbmults(3);case'bggr'colormask(2:2:,2:2:)=wbmults(1);colormask(1:2:,1:2:)=wbmults(3);case'grbg'colormask(1:2:,2:2:)=wbmults(1);colormask(2:2:,1:2:)=wbmults(3);case'gbrg'colormask(2:2:,1:2:)=wbmults(1);colormask(1:2:,2:2:)=wbmults(3);

完成白平衡调整后的图像如下:

色彩差值

色彩差值又称去马赛克,经过色彩插值之后原来的灰度图像就成为了一幅三通道的彩色图像。空间插值有非常多的方法,这里为了方便我们使用MATLAB内置的demosaic函数,它能够直接把单通道的灰度图像转换为三通道的彩色图像。由于demosaic函数的输入必须为uint8或uint16类型,我们需要把原来的double型先转换为uint16型。注意这里的'rggb'应该根据相机的具体情况而调整。

12
temp=uint16(balanced_bayer/max(balanced_bayer(:))*(2^16-1));lin_rgb=double(demosaic(temp,'rggb'))/(2^16-1);

完成这一步之后我们就得到了最原始的彩色信息。一些应用中所需要的就是这幅图像的数据,可以使用imwrite函数将其保存在硬盘中。后续的色彩空间转换、Gamma校正等步骤视情况决定是否需要执行。色彩插值后得到的图像如下:

色彩空间转换

A_{sRGB\leftarrowCamera}=(A_{Camera\leftarrowXYZ}\cdotA_{XYZ\leftarrowsRGB})^{-1}AsRGB←Camera=(ACamera←XYZ​⋅AXYZ←sRGB​)−1

不同相机的Camera不同,因此我们必须获得适合自己相机的A_{Camera\leftarrowXYZ}ACamera←XYZ​。在Dcraw的C文件中收集了市面上大多数相机的,可以在中的adobe_coeff函数下找到。adobe_coeff函数下的数字是A_{Camera\leftarrowXYZ}ACamera←XYZ​中各元素乘以10000后逐行排列的数值。

我使用的CanonEOS1100D有:

12
{"CanonEOS1100D",0,0x3510,{6444,-904,-893,-4563,12308,2535,-903,2016,6728}}

我们得到的数值对应了矩阵中逐列排列的各元素。以CanonEOS1100D为例,有:

A_{Camera\leftarrowXYZ}=\frac{1}{10000}\begin{bmatrix}6444-904-893\\-4563123082535\\-90320166728\{bmatrix}ACamera←XYZ​=100001​⎣⎡​6444−4563−903​−904123082016​−89325356728​⎦⎤​

而sRGB-to-XYZ可以在国际照明委员会(CIE)公布的标准中查到,有:

A_{XYZ\leftarrowsRGB}=\begin{bmatrix}0.41245640.35757610.1804375\\0.21267290.71515220.0721750\\0.01933390.11919200.9503041\{bmatrix}AXYZ←sRGB​=⎣⎡​0.41245640.21267290.0193339​0.35757610.71515220.1191920​0.18043750.07217500.9503041​⎦⎤​

得到了这两个矩阵,自然也就能够算出A_{sRGB\leftarrowCamera}AsRGB←Camera​。在色彩空间转换过程中必须考虑这样一个问题:由于白色(客观意义上的白色)在相机的RGB空间和sRGB空间中都是用[1,1,1]^{T}[1,1,1]T来表示,而我们上述白平衡调整的目的就是要确保图像中白色的部分在任何空间中都呈现出白色。因此以下关系必须成立:

\begin{bmatrix}1\\1\\1\{bmatrix}_{Camera}=\Bigg[A_{Camera\leftarrowsRGB}\Bigg]\begin{bmatrix}1\\1\\1\{bmatrix}_{sRGB}⎣⎡​111​⎦⎤​Camera​=[ACamera←sRGB​]⎣⎡​111​⎦⎤​sRGB​

根据线性代数的知识,要满足上式,矩阵A_{Camera\leftarrowsRGB}ACamera←sRGB​的每一行元素之和必须为1,因此在MATLAB中我们必须再加上一个步骤,将A_{Camera\leftarrowsRGB}ACamera←sRGB​各行归一化为1。色彩空间变换的代码如下。注意矩阵XYZ2Cam请根据自己使用的相机型号进行修改。

123456789
sRGB2XYZ=[0.41245640.35757610.1804375;0.21267290.71515220.0721750;0.01933390.11919200.9503041];%sRGB2XYZisanunchangedstandardXYZ2Cam=[6444,-904,-893;-4563,12308,2535;-903,2016,6728]/10000;%HereXYZ2CamisonlyforCanonEOS1100D,canbefoundinadobe_=XYZ2Cam*sRGB2XYZ;sRGB2Cam=sRGB2Cam./repmat(sum(sRGB2Cam,2),1,3);%normalizeeachrowsofsRGB2Camto1Cam2sRGB=(sRGB2Cam)^-1;lin_srgb=apply_cmatrix(lin_rgb,Cam2sRGB);lin_srgb=max(0,min(lin_srgb,1));%Alwayskeepimageclippedb/w0-1

其中apply_cmatrix函数就是把我们得到的A_{sRGB\leftarrowCamera}AsRGB←Camera​应用到原图像的各个通道上:

1234567891011
functioncorrected=apply_cmatrix(im,cmatrix)%%oldcolorplanestoformthenewcolorplanes,equivalenttobutmuch%(im,3)~=3error('ApplycmatrixtoRGBimageonly.');r=cmatrix(1,1)*im(:,:,1)+cmatrix(1,2)*im(:,:,2)+cmatrix(1,3)*im(:,:,3);g=cmatrix(2,1)*im(:,:,1)+cmatrix(2,2)*im(:,:,2)+cmatrix(2,3)*im(:,:,3);b=cmatrix(3,1)*im(:,:,1)+cmatrix(3,2)*im(:,:,2)+cmatrix(3,3)*im(:,:,3);corrected=cat(3,r,g,b);

经过色彩空间变换后的图像如下,可以看出相比变换之前的图像,各个彩色色块饱和度明显增加。

亮度校正与伽马校正

123
grayim=rgb2gray(lin_srgb);%Consideronlygraychannelgrayscale=0.25/mean(grayim(:));bright_srgb=min(1,lin_srgb*grayscale);%Alwayskeepimagevaluelessthan1

亮度校正后的图像如下所示:

接下来是Gamma校正。Gamma曲线是图像、信号处理领域使用最为广泛的非线性处理,我们最常见的就是Photoshop中的「曲线」功能,如果将曲线拉成y=x^{\gamma}y=xγ的形状,就相当于对图像做了一次Gamma校正。在sRGB的官方文档中使用的是\gamma=1/2.4γ=1/2.4,并在函数值较小的部分应用了小范围的线性函数。但是现在大多数平台(Windows,Mac)都使用了\gamma=1/2.2γ=1/2.2的曲线,因此这里我们也使用2.2作为参数,并且不考虑局部的线性化。如果需要精确的sRGB标准的校正函数,可以查看其官方文档。

1
nl_srgb=bright_srgb.^(1/2.2);

经过Gamma校正后的图像如下。由于使用的Gamma曲线是一条凸函数,相当于把图像暗部的细节展宽,因此得到的图像要比校正前更亮。

至此一套通用的RAW文件处理流程就完成了,接下来可以根据需要再进行一系列的处理过程。

◎直接读取的tiff文件

◎线性处理后的图像

◎白平衡调整后的图像

◎色彩插值后的图像

◎转换至sRGB空间后的图像

◎经过亮度校正后的图像

◎经过Gamma校正后的图像

版权声明:本站所有作品(图文、音视频)均由用户自行上传分享,仅供网友学习交流,不声明或保证其内容的正确性,如发现本站有涉嫌抄袭侵权/违法违规的内容。请举报,一经查实,本站将立刻删除。

相关推荐