MATLAB图像处理:121:实现数码相机处理流水线

您所在的位置:网站首页 matlab读取图片没有读取权限 MATLAB图像处理:121:实现数码相机处理流水线

MATLAB图像处理:121:实现数码相机处理流水线

2023-05-15 18:12| 来源: 网络整理| 查看: 265

本示例说明如何实现从 RAW 拜耳模式滤色器阵列 (CFA) 图像渲染 RGB 图像的相机处理流水线。

数码单镜头反光 (DSLR) 相机和许多现代手机相机可以将从相机传感器收集的数据直接保存到 RAW 文件中。RAW 数据的每个像素是相应相机光电传感器捕获的光量。数据取决于相机硬件的固定特性,例如每个光电传感器对电磁光谱特定波长范围的灵敏度。数据还取决于相机采集设置,例如曝光时间和场景因素,例如光源。

根据图像元数据中可用的信息,可以有多种方法来实现产生美观结果的流水线。该示例显示了传统相机处理流水线中使用与 RAW 数据相关联的元数据子集的一系列操作。

导入 RAW 文件内容线性化 CFA 图像将 CFA 数据缩放到合适的范围应用白平衡调整去马赛克拜耳模式将去马赛克图像转换为 sRGB 颜色空间

本示例还显示了没有 RAW 文件元数据时如何从 RAW 图像创建 RGB 图像。

读取 RAW 文件内容

数码相机创建的 RAW 文件包含:

由相机的光电传感器记录的 CFA 图像元数据,其中包含渲染 RGB 图像所需的所有信息

使用rawread函数从 RAW 文件中读取拜耳模式 CFA 图像。

fileName = "colorCheckerTestImage.NEF"; cfaImage = rawread(fileName);

列出有关cfaImage变量的信息并显示图像。

whos cfaImage Name Size Bytes Class Attributes ​ cfaImage 4012x6034 48416816 uint16 imshow(cfaImage,[]) title("RAW CFA Image")

使用rawinfo函数读取 RAW 文件元数据。

cfaInfo = rawinfo(fileName);

元数据包含的几个字段的信息,可以用于处理 RAW 图像。例如,显示ImageSizeInfo字段的内容。元数据表明 CFA 光电传感器阵列中的列多于可见图像中的列。当相机遮住光传感器的一部分以防止这些部分捕获任何光线时,通常会出现差异。这可以准确测量传感器的黑电平。

disp(cfaInfo.ImageSizeInfo) CFAImageSize: [4012 6080] VisibleImageSize: [4012 6034] VisibleImageStartLocation: [1 1] PixelAspectRatio: 1 ImageRotation: 0 RenderedImageSize: [4012 6034]

RAW 文件元数据还包括启用线性化、黑电平校正、白平衡和其他将 RAW 数据转换为 RGB 所需的处理操作的信息。

colorInfo = cfaInfo.ColorInfo colorInfo = struct with fields: LinearizationTable: [0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 ... ] BlackLevel: [0 0 0 0] WhiteLevel: [3827 3827 3827 3827] CameraToXYZ: [3x3 double] CameraTosRGB: [3x3 double] CameraAsTakenWhiteBalance: [495 256 256 324] D65WhiteBalance: [2.1900 0.9286 0.9286 1.0595] ICCProfile: []线性化 CFA 图像

许多相机在将采集到的信号存储为 RAW 文件之前对其应用非线性范围压缩。相机通常将此范围压缩存储为查找表。

绘制图像元数据LinearizationTable字段中值的代表性子集。高于maxLinValue值的值继续做线性增加。

maxLinValue = 10^4; linTable = colorInfo.LinearizationTable; plot(0:maxLinValue-1,linTable(1:maxLinValue)) title("Linearization Table")

数码相机处理流水线上的处理操作通常在线性数据上执行。要生成线性数据,您必须反转非线性范围压缩。rawread函数自动执行此操作并返回线性化的光值。

将像素值缩放到合适的范围执行黑电平校正

RAW 图像没有真正的黑色值。即使快门关闭,流过传感器的电流也会导致非零光子计数。相机使用遮罩像素的值来计算 CFA 图像的黑电平。要缩放图像,请从 CFA 图像数据中减去测量的黑电平。

RAW 文件格式可以以不同的格式报告此黑电平。本示例中图像的 RAW 文件元数据将黑电平指定为矢量,CFA 图像的每个通道有一个元素。其他 RAW 文件格式(例如 DNG)将黑电平指定为从 CFA 可见部分的左上角开始的重复m × n矩阵。

从BlackLevel元数据字段中获取 RAW 数据的黑电平值。

blackLevel = colorInfo.BlackLevel;

要执行黑电平校正,首先将黑电平矢量转换为 2×2 矩阵。对于将黑电平指定为矩阵的 RAW 图像,请省略此步骤。

blackLevel = reshape(blackLevel,[1 1 numel(blackLevel)]); blackLevel = planar2raw(blackLevel);

将黑电平矩阵复制为可见图像的大小。

repeatDims = cfaInfo.ImageSizeInfo.VisibleImageSize ./ size(blackLevel); blackLevel = repmat(blackLevel,repeatDims);

从 CFA 图像矩阵中减去黑电平矩阵。

cfaImage = cfaImage - blackLevel;钳制负像素值

要校正小于黑电平值的 CFA 数据值,请将值钳制为 0。

cfaImage = max(0,cfaImage);缩放像素值

RAW 文件元数据通常将白电平表示为数据类型允许的最大值。如果此白电平值远高于图像中的最高强度值,则使用此白电平值进行缩放会导致图像比应有的亮度要暗。为避免这种情况,请使用图像中找到的最大像素值缩放 CFA 图像。

cfaImage = double(cfaImage); maxValue = max(cfaImage(:)) maxValue = 3366 cfaImage = cfaImage ./ maxValue;调整白平衡

白平衡是从渲染图像中去除不真实的色偏的过程,使其看起来更接近人眼看到的对象。

从元数据中获取白平衡值。有两种类型的白平衡元数据可用。示例的此步骤使用CameraAsTakenWhiteBalance字段缩放颜色通道来平衡线性像素值。本示例稍后在流水线中使用D65WhiteBalance字段将颜色调整为 D65 白点。

whiteBalance = colorInfo.CameraAsTakenWhiteBalance whiteBalance = 1×4 ​ 495 256 256 324

缩放乘数,使绿色通道的值为1。

gLoc = strfind(cfaInfo.CFALayout,"G"); gLoc = gLoc(1); whiteBalance = whiteBalance/whiteBalance(gLoc); ​ whiteBalance = reshape(whiteBalance,[1 1 numel(whiteBalance)]); whiteBalance = planar2raw(whiteBalance);

将白平衡矩阵复制为可见图像的大小。

whiteBalance = repmat(whiteBalance,repeatDims); cfaWB = cfaImage .* whiteBalance;

将 CFA 图像转换为 16 位图像。

cfaWB = im2uint16(cfaWB);去除马赛克

通过去除马赛克,将拜耳编码的 CFA 图像转换为真彩色图像。真彩色图像位于相机线性空间中。

cfaLayout = cfaInfo.CFALayout; imDebayered = demosaic(cfaWB,cfaLayout); imshow(imDebayered) title("Demosaiced RGB Image in Linear Camera Space")

从相机色彩空间转换为 RGB 色彩空间

元数据支持两个选项,用于将图像从线性相机空间转换为经过伽马校正的 RGB 颜色空间。可以使用CameraToXYZ元数据字段通过 XYZ 配置连接空间 (PCS) 将数据从相机线性空间转换为 RGB 颜色空间,也可以使用CameraTosRGB元数据字段,直接将图像从相机线性空间转换为 RGB 颜色空间。

使用配置连接空间转换

从元数据字段CameraToXYZ中,获取相机线性空间和XYZ配置连接空间之间的变换矩阵。这个矩阵强加了一个 RGB 顺序。换句话说:

[X,Y,Z]' = CameraToXYZ.*[R,G,B]' cam2xyzMat = colorInfo.CameraToXYZ cam2xyzMat = 3×3 ​ 1.5573 0.1527 0.0794 0.6206 0.9012 -0.2690 0.0747 -0.3117 1.4731

根据 D65 白点对cam2xyzMat矩阵进行归一化。从D65WhiteBalance元数据字段中获取 XYZ 标准化值。

whiteBalanceD65 = colorInfo.D65WhiteBalance whiteBalanceD65 = 1×4 ​ 2.1900 0.9286 0.9286 1.0595

白平衡乘数根据CFALayout元数据字段排序。重新排序乘数以匹配cam2xyzMat矩阵的行顺序。

cfaLayout = cfaInfo.CFALayout; wbIdx(1) = strfind(cfaLayout,"R"); gidx = strfind(cfaLayout,"G"); wbIdx(2) = gidx(1); wbIdx(3) = strfind(cfaLayout,"B"); ​ wbCoeffs = whiteBalanceD65(wbIdx); cam2xyzMat = cam2xyzMat ./ wbCoeffs;

使用imapplymatrix函数,将图像从相机线性空间转换为 XYZ 颜色空间。然后,将图像转换为 sRGB 颜色空间并使用xyz2rgb函数应用伽马校正。

imXYZ = imapplymatrix(cam2xyzMat,im2double(imDebayered)); srgbPCS = xyz2rgb(imXYZ,OutputType="uint16"); imshow(srgbPCS) title("sRGB Image Using PCS")

使用来自 RAW 文件元数据的转换矩阵

使用元数据字段CameraTosRGB中的变换矩阵将图像从线性相机空间转换为线性 RGB 颜色空间。

cam2srgbMat = colorInfo.CameraTosRGB; imTransform = imapplymatrix(cam2srgbMat,imDebayered,"uint16");

应用 gamma 校正将图像从线性 sRGB 颜色空间带到 sRGB 颜色空间。

srgbTransform = lin2rgb(imTransform); imshow(srgbTransform) title("sRGB Image Using Transformation Matrix")

在没有元数据的情况下将 RAW 转换为 RGB

可以使用raw2rgb函数将 RAW 数据直接转换为 RGB 图像。raw2rgb函数提供可比较的结果,作为根据您的数据和采集设置量身定制的自定义处理流水线。但是,raw2rgb函数不提供与自定义流水线相同的微调精度和灵活性。

使用raw2rgb函数将 RAW 文件中的图像数据转换为 sRGB 色彩空间。

srgbAuto = raw2rgb(fileName); imshow(srgbAuto) title("sRGB Image Using raw2rgb Function")

将raw2rgb转换结果与使用 PCS 和转换矩阵的完整相机处理流水线获得的结果进行比较。

montage({srgbPCS,srgbTransform,srgbAuto},Size=[1 3]); title("sRGB Image Using PCS, raw2rgb Function, and Transformation Matrix (Left to Right)")

注:本文根据MATLAB官网内容修改而成。

以下的免费视频教程,特点是没有PPT,不掺水,直接编程环境下的实操课程:

用100分钟查看免费的《MATLAB编程》视频课程 1data.pro

欢迎您进一步了解以下MATLAB系列文章:

吃小羊:MATLAB作图实例:00:索引吃小羊:MATLAB金融工具箱:00:索引吃小羊:MATLAB图像处理:00:索引



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3